1. 程式人生 > >spring之aware介面

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感興趣的小夥伴可以自行檢視