ApplicationContextAware
作用
Spring中管理的对象有两类,一类是用户自定义的对象,一类是Spring容器对象,比如applicationContext、beanFactory等。用户自定义的对象,在注入时可以直接使用@Autowared等方法,但是如果需要使用容器对象,该怎么注入呢?
Spring提供了一个扩展方法,即ApplicationContextAware接口,实现容器对象的注入。
这个接口里面只有一个方法,即setApplicationContext
publicinterfaceApplicationContextAwareextendsAware{voidsetApplicationContext(ApplicationContextvar1)throwsBeansException;}
使用方法
创建即ApplicationContextAware接口的实现类,实现类中定义局部变量context,实现setApplicationContext方法,将容器对象接收到context中。
publicclassApplicationContextUtilimplementsApplicationContextAware{privatestaticApplicationContextcontext;publicvoidsetApplicationContext(ApplicationContextcontext)throwsBeansException{this.context=context;}publicstaticApplicationContextgetContext(){returncontext;}}
context变量不是必须的,如果后续业务中需要使用context,就保存下来,如果只在bean初始化时用一次就不需要。
执行时机
作为第一个BeanPostProcessor执行。
源码解读
首先看一下bean初始化时各个扩展点的执行顺序。 在bean初始化方法AbstractAutowireCapableBeanFactory#initializeBean()
中,可以看出执行顺序是:
先调用bean的构造函数
再调用set方法
再调用beanPostProcessorsBeforeInitialization
调用init-method
调用beanPostProcessorsAfterInitialization
protectedObjectinitializeBean(StringbeanName,Objectbean,@NullableRootBeanDefinitionmbd){if(System.getSecurityManager()!=null){AccessController.doPrivileged((PrivilegedAction<Object>)()->{invokeAwareMethods(beanName,bean);returnnull;},getAccessControlContext());}else{invokeAwareMethods(beanName,bean);}ObjectwrappedBean=bean;if(mbd==null||!mbd.isSynthetic()){wrappedBean=applyBeanPostProcessorsBeforeInitialization(wrappedBean,beanName);}try{invokeInitMethods(beanName,wrappedBean,mbd);}catch(Throwableex){thrownewBeanCreationException((mbd!=null?mbd.getResourceDescription():null),beanName,"Invocationofinitmethodfailed",ex);}if(mbd==null||!mbd.isSynthetic()){wrappedBean=applyBeanPostProcessorsAfterInitialization(wrappedBean,beanName);}returnwrappedBean;}
其中,ApplicationContextAware是在beanPostProcessorsBeforeInitialization阶段。怎么知道的呢?
在AbstractApplicationContext#refresh()
方法中,进行各个扩展点实现的设置。
publicvoidrefresh()throwsBeansException,IllegalStateException{synchronized(this.startupShutdownMonitor){//Preparethiscontextforrefreshing.prepareRefresh();//Tellthesubclasstorefreshtheinternalbeanfactory.ConfigurableListableBeanFactorybeanFactory=obtainFreshBeanFactory();//Preparethebeanfactoryforuseinthiscontext.prepareBeanFactory(beanFactory);try{//Allowspost-processingofthebeanfactoryincontextsubclasses.postProcessBeanFactory(beanFactory);//Invokefactoryprocessorsregisteredasbeansinthecontext.invokeBeanFactoryPostProcessors(beanFactory);//Registerbeanprocessorsthatinterceptbeancreation.registerBeanPostProcessors(beanFactory);//Initializemessagesourceforthiscontext.initMessageSource();//Initializeeventmulticasterforthiscontext.initApplicationEventMulticaster();//Initializeotherspecialbeansinspecificcontextsubclasses.onRefresh();//Checkforlistenerbeansandregisterthem.registerListeners();//Instantiateallremaining(non-lazy-init)singletons.finishBeanFactoryInitialization(beanFactory);//Laststep:publishcorrespondingevent.finishRefresh();}catch(BeansExceptionex){......省略......}finally{......省略......}}}
其中,prepareBeanFactory()
方法中,可以看到,将ApplicationContextAwareProcessor
加到BeanPostProcessor中了。
protectedvoidprepareBeanFactory(ConfigurableListableBeanFactorybeanFactory){//Telltheinternalbeanfactorytousethecontext'sclassloaderetc.beanFactory.setBeanClassLoader(getClassLoader());beanFactory.setBeanExpressionResolver(newStandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));beanFactory.addPropertyEditorRegistrar(newResourceEditorRegistrar(this,getEnvironment()));//Configurethebeanfactorywithcontextcallbacks.beanFactory.addBeanPostProcessor(newApplicationContextAwareProcessor(this));......省略......//Registerearlypost-processorfordetectinginnerbeansasApplicationListeners.beanFactory.addBeanPostProcessor(newApplicationListenerDetector(this));......省略......}
再看一下ApplicationContextAwareProcessor
,它实现了BeanPostProcessor接口,覆写了postProcessBeforeInitialization()
方法,在方法里面,如果发现bean是ApplicationContextAware
类型,就调用setApplicationContext()方法。
classApplicationContextAwareProcessorimplementsBeanPostProcessor{privatefinalConfigurableApplicationContextapplicationContext;privatefinalStringValueResolverembeddedValueResolver;/***CreateanewApplicationContextAwareProcessorforthegivencontext.*/publicApplicationContextAwareProcessor(ConfigurableApplicationContextapplicationContext){this.applicationContext=applicationContext;this.embeddedValueResolver=newEmbeddedValueResolver(applicationContext.getBeanFactory());}@Override@NullablepublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName)throwsBeansException{if(!(beaninstanceofEnvironmentAware||beaninstanceofEmbeddedValueResolverAware||beaninstanceofResourceLoaderAware||beaninstanceofApplicationEventPublisherAware||beaninstanceofMessageSourceAware||beaninstanceofApplicationContextAware)){returnbean;}AccessControlContextacc=null;if(System.getSecurityManager()!=null){......省略......}else{invokeAwareInterfaces(bean);}returnbean;}privatevoidinvokeAwareInterfaces(Objectbean){if(beaninstanceofEnvironmentAware){((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment());}if(beaninstanceofEmbeddedValueResolverAware){((EmbeddedValueResolverAware)bean).setEmbeddedValueResolver(this.embeddedValueResolver);}if(beaninstanceofResourceLoaderAware){((ResourceLoaderAware)bean).setResourceLoader(this.applicationContext);}if(beaninstanceofApplicationEventPublisherAware){((ApplicationEventPublisherAware)bean).setApplicationEventPublisher(this.applicationContext);}if(beaninstanceofMessageSourceAware){((MessageSourceAware)bean).setMessageSource(this.applicationContext);}if(beaninstanceofApplicationContextAware){((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);}}}