ApplicationContextAware和BeanFactoryAware使用理解

1.Spring容器會自動把上下文環境對象調用ApplicationContextAware接口中的setApplicationContext方法;當一個類實現了這個接口之後,這個類就可以非常方便的獲取到ApplicationContext中的所有的bean;簡而言之,言而總之,此類可以獲取到spring配置文件中所有的bean對象。

2.基本原理見如下代碼,核心類:ApplicationContextAwareProcessor

public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
	AccessControlContext acc = null;

	if (System.getSecurityManager() != null &&
			(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||    bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||    bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
	}

	if (acc != null) {
		AccessController.doPrivileged(new PrivilegedAction<Object>() {
			public Object run() {
				invokeAwareInterfaces(bean);
				return null;
			}
		}, acc);
	}
	else {
		invokeAwareInterfaces(bean);
	}

	return bean;
}

private void invokeAwareInterfaces(Object bean) {
	if (bean instanceof Aware) {
		if (bean instanceof EnvironmentAware) {
			((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment());
			}
		if (bean instanceof EmbeddedValueResolverAware) {
			((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(
				new EmbeddedValueResolver(this.applicationContext.getBeanFactory()));
		}
		if (bean instanceof ResourceLoaderAware) {
			((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
		}
		if (bean instanceof ApplicationEventPublisherAware) {
			((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
		}
		if (bean instanceof MessageSourceAware) {
			((MessageSourceAware) bean).setMessageSource(this.applicationContext);
		}
		if (bean instanceof ApplicationContextAware) {
			((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
		}
	}
}

在啓動Spring容器創建bean的時候會執行postProcessBeforeInitialization這個方法,發現實現了Aware接口的類(例如最後一個ApplicationContextAware),都會加載spring的applicationContext。

3.代碼實例講解(此處講解通過實現BeanFactoryAware接口將bean註冊到beanfactory中):
首先通過實現BeanFactoryAware接口將bean註冊到spring容器中。

@Component
public class BeanFactoryHelper implements BeanFactoryAware {

    private static BeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    public static BeanFactory getBeanFactory() {
        return this.beanFactory;
    }
}

//獲取beanFactory並註冊到spring上下文中
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) BeanFactoryHolder.getBeanFactory();

String beanName = "test";
beanFactory.destroySingleton(beanName);

beanFactory.registerSingleton(beanName, singletonObject);

註冊到spring上下文之後就可以通過實現ApplicationContextAware接口來獲取bean對象:

@Component
public class ApplicationContextHelper implements ApplicationContextAware {
    private static ApplicationContext ctx;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.ctx = applicationContext;
    }

    public static ApplicationContext getApplicationContext() {
        return this.ctx;
    }

    public static Object getBean(String beanName) {
        return this.ctx.getBean(beanName);
    }

    public static <T> T getBean(Class<T> clazz) {
        return this.ctx.getBean(clazz);
    }

    public static <T> T getBean(String beanName, Class<T> clazz) {
        try {
            return this.ctx.getBean(beanName, clazz);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

有問題歡迎各位一起討論交流。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章