首页>>后端>>Spring->Spring扩展点之ApplicationContextAware

Spring扩展点之ApplicationContextAware

时间:2023-11-29 本站 点击:0

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);}}}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Spring/330.html