本節主要學習Bean對IOC容器的感知
容器管理的Bean一般不需要了解容器的狀態和直接使用容器,但在某些情況下,需要在Bean中直接對IOC容器進行操作,這時候就需要在Bean中設定對容器的感知。Spring IOC容器也提供了該功能,它是通過特定的aware接口完成的。aware接口有以下這些:
- BeanNameAware ,可以在Bean中得到它在IOC容器中的Bean實例名稱
- BeanFactoryAware,可以在Bean中得到Bean所在的IOC容器,從而直接在Bean中使用IOC容器的服務。
- ApplicationContextAware,可以在Bean中得到Bean所在的應用上下文,從而直接在Bean中使用應用上下文的服務。
- MessageSourceAware,在Bean中可以得到消息源
- ApplicationEventpublisherAware,在Bean中得到應用上下文的事件發佈器,從而可以在Bean中發佈應用上下文的事件。
- ResourceLoaderAware,在Bean中得到ResourceLoader,從而在Bean中得到ResourceLoader加載外部對應的Resource資源。
比如ApplicationContextAware
public interface ApplicationContextAware extends Aware {
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
這個setApplicationContext方法的回調是由容器自動完成的.
ApplicationContextAwareProcessor作爲BeanPostProcessor的實現,對一系列的aware進行了調用。
class ApplicationContextAwareProcessor implements BeanPostProcessor {
private final ConfigurableApplicationContext applicationContext;
private final StringValueResolver embeddedValueResolver;
/**
* Create a new ApplicationContextAwareProcessor for the given context.
*/
public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
}
@Override
@Nullable
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((PrivilegedAction<Object>) () -> {
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(this.embeddedValueResolver);
}
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);
}
}
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
}
postProcessBeforeInitialization會在初始化Bean的實現過程中被調用,從而實現對aware接口的相關注入。