spring之aware介面
實現org.springframework.beans.factory.aware子介面的Bean類在建立時會在呼叫該bean的init方法之前呼叫aware子介面的相應方法,舉幾個類來說明下:
org.springframework.context.ApplicationContextAware的setApplicationContext方法
org.springframework.beans.factory.BeanFactoryAware的setBeanFactory(BeanFactory beanFactory)方法等
通過實現ApplicationContextAware介面,我們就能獲取到當前執行的ApplicationContext物件,通過實現BeanFactoryAware介面就能獲取到當前系統使用的BeanFactory物件。
但是aware子介面是怎麼被呼叫的呢?這就需要涉及到bean的建立過程中的一個環節:
1.先看org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory類的方法:
@Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { result = beanProcessor.postProcessBeforeInitialization(result, beanName); if (result == null) { return result; } } return result; }
2.這裡會通過getBeanPostProcessors方法獲取該BeanFactory物件具體支援的所有BeanPostProcessor,這裡用到了java的多型特性,這裡以
org.springframework.beans.factory.support.DefaultListableBeanFactory類為例來講述該類預設提供的BeanPostProcessors如下(所以由DefaultListableBeanFactory類建立的bean物件都要經歷這些BeanPostProcessor的摧殘
[org.springframework.context.support.ApplicationContextAwareProcessor, org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker, org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor, org.springframework.context.annotation.ConfigurationClassPostProcessor$EnhancedConfigurationBeanPostProcessor,
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor, org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor,
org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor, org.springframework.context.support.ApplicationListenerDetector]
3.接下來以ApplicationContextAwareProcessor類為例來講述該類的postProcessBeforeInitialization方法:
@Override
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>() {
@Override
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(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); } } }
所以想要獲取ApplicationContext物件,可以通過實現ApplicationContextAware介面,並實現setApplicationContext介面來獲取。
至於DefaultListableBeanFactory類中的其他的BeanPostProcessor感興趣的小夥伴可以自行檢視