1.ApplicationContext的初始化以及销毁
对于BeanFactory也有一个初始化和销毁关闭的过程,比如编程式的容器如下:
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainApp.class);
构造方法如下:
public AnnotationConfigApplicationContext(Class<?>... componentClasses) { this(); register(componentClasses); refresh(); }
refresh是IoC的开始,方法如下:
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset ‘active‘ flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring‘s core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory 是为启动过程做了一些准备工作,为容器配置了Classloader、PropertyEditor、BeanPostProcessor、Environment环境等信息,从而为容器启动做了必要的准备工作。
/** * Configure the factory‘s standard context characteristics, * such as the context‘s ClassLoader and post-processors. * @param beanFactory the BeanFactory to configure */ protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // Tell the internal bean factory to use the context‘s class loader etc. beanFactory.setBeanClassLoader(getClassLoader()); beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // Configure the bean factory with context callbacks. beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); // BeanFactory interface not registered as resolvable type in a plain factory. // MessageSource registered (and found for autowiring) as a bean. beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // Register early post-processor for detecting inner beans as ApplicationListeners. beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // Detect a LoadTimeWeaver and prepare for weaving, if found. if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } // Register default environment beans. if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }
同时,容器在关闭时也会做一系列的操作。在doClose中,先发出容器关闭的信号、然后将Bean逐个关闭,最后关闭容器自身。org.springframework.context.support.AbstractApplicationContext#doClose:
protected void doClose() { // Check whether an actual close attempt is necessary... if (this.active.get() && this.closed.compareAndSet(false, true)) { if (logger.isDebugEnabled()) { logger.debug("Closing " + this); } LiveBeansView.unregisterApplicationContext(this); try { // Publish shutdown event. publishEvent(new ContextClosedEvent(this)); } catch (Throwable ex) { logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex); } // Stop all Lifecycle beans, to avoid delays during individual destruction. if (this.lifecycleProcessor != null) { try { this.lifecycleProcessor.onClose(); } catch (Throwable ex) { logger.warn("Exception thrown from LifecycleProcessor on context close", ex); } } // Destroy all cached singletons in the context‘s BeanFactory. destroyBeans(); // Close the state of this context itself. closeBeanFactory(); // Let subclasses do some final clean-up if they wish... onClose(); // Reset local application listeners to pre-refresh state. if (this.earlyApplicationListeners != null) { this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); } // Switch to inactive. this.active.set(false); } }
2. Bean的生命周期
容器的实现是通过IoC来管理Bean的生命周期来实现的。Spring IoC容器在对Bean的生命周期进行管理时提供了Bean生命周期的各个时间点的回调。IoC中Bean的生命周期如下:
(1)Bean实例的创建
(2)为Bean实例设置属性
(3)调用Bean的初始化方法
(4)应用可以通过IoC容器使用Bean
(5)容器关闭时,调用Bean的销毁方法
在上一节IoC依赖注入过程中研究了Bean实例的创建、设置属性、调用Bean的初始化。
(1) 实例的创建实际就是反射或者CGlib代理生成对象
(2) 设置属性实际就是依赖注入
(3) Bean的初始化方法: 依赖注入完成之后调用初始化initializeBean方法
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; } private void invokeAwareMethods(String beanName, Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ClassLoader bcl = getBeanClassLoader(); if (bcl != null) { ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); } } if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } } protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) throws Throwable { boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { if (logger.isTraceEnabled()) { logger.trace("Invoking afterPropertiesSet() on bean with name ‘" + beanName + "‘"); } if (System.getSecurityManager() != null) { try { AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> { ((InitializingBean) bean).afterPropertiesSet(); return null; }, getAccessControlContext()); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { ((InitializingBean) bean).afterPropertiesSet(); } } if (mbd != null && bean.getClass() != NullBean.class) { String initMethodName = mbd.getInitMethodName(); if (StringUtils.hasLength(initMethodName) && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { invokeCustomInitMethod(beanName, bean, mbd); } } }
在调用初始化方法之前,会先调用invokeAwareMethods 一系列的ware接口实现,把相关的BeanName、BeanClassLoader以及BeanFactory注入到Bean中去。
接着调用invokeInitMethods方法,会看到启动afterPropertiesSet 的过程,当然这需要Bean实现InitializingBean 接口,对应的初始化处理可以在InitializingBean 接口的afterPropertiesSet 方法实现,同样是对Bean的一个回调。
最后还会判断是否有initMethod,如果有那么通过invokeCustomInitMethod 直接调用最终完成对Bean的初始化。
protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd) throws Throwable { String initMethodName = mbd.getInitMethodName(); Assert.state(initMethodName != null, "No init method set"); Method initMethod = (mbd.isNonPublicAccessAllowed() ? BeanUtils.findMethod(bean.getClass(), initMethodName) : ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName)); if (initMethod == null) { if (mbd.isEnforceInitMethod()) { throw new BeanDefinitionValidationException("Could not find an init method named ‘" + initMethodName + "‘ on bean with name ‘" + beanName + "‘"); } else { if (logger.isTraceEnabled()) { logger.trace("No default init method named ‘" + initMethodName + "‘ found on bean with name ‘" + beanName + "‘"); } // Ignore non-existent default lifecycle methods. return; } } if (logger.isTraceEnabled()) { logger.trace("Invoking init method ‘" + initMethodName + "‘ on bean with name ‘" + beanName + "‘"); } Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod); if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { ReflectionUtils.makeAccessible(methodToInvoke); return null; }); try { AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> methodToInvoke.invoke(bean), getAccessControlContext()); } catch (PrivilegedActionException pae) { InvocationTargetException ex = (InvocationTargetException) pae.getException(); throw ex.getTargetException(); } } else { try { ReflectionUtils.makeAccessible(methodToInvoke); methodToInvoke.invoke(bean); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } } }
invokeCustomInitMethod 方法调用中,首先得到Bean定义的initMethod方法,然后通过JDK的反射得到Method对象,直接调用在Bean定义中声明的初始化方法。
(4) IoC容器使用Bean
(5) Bean的销毁
上面容器的销毁中 destroyBeans 是销毁Bean,经过一系列的调用会调到:org.springframework.beans.factory.support.DisposableBeanAdapter#destroy
@Override public void destroy() { if (!CollectionUtils.isEmpty(this.beanPostProcessors)) { for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) { processor.postProcessBeforeDestruction(this.bean, this.beanName); } } if (this.invokeDisposableBean) { if (logger.isTraceEnabled()) { logger.trace("Invoking destroy() on bean with name ‘" + this.beanName + "‘"); } try { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> { ((DisposableBean) this.bean).destroy(); return null; }, this.acc); } else { ((DisposableBean) this.bean).destroy(); } } catch (Throwable ex) { String msg = "Invocation of destroy method failed on bean with name ‘" + this.beanName + "‘"; if (logger.isDebugEnabled()) { logger.warn(msg, ex); } else { logger.warn(msg + ": " + ex); } } } if (this.destroyMethod != null) { invokeCustomDestroyMethod(this.destroyMethod); } else if (this.destroyMethodName != null) { Method methodToInvoke = determineDestroyMethod(this.destroyMethodName); if (methodToInvoke != null) { invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke)); } } }
首先调用 postProcessBeforeDestruction,然后调用Bean的destroy方法,最后是对Bean的自定义销毁方法的调用,和前面初始化的过程类型。
测试如下:
package qz; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; //@Component //@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS) //@Lazy public class UserService implements InitializingBean, DisposableBean, BeanNameAware { // 构造 public UserService() { System.out.println("=============UserService====="); } // aware 接口 @Override public void setBeanName(String name) { System.out.println("====setBeanName====" + name); } @PostConstruct public void PostConstruct() { System.out.println("PostConstruct ============="); } // InitializingBean @Override public void afterPropertiesSet() throws Exception { System.out.println("====afterPropertiesSet===="); } // initMethod public void initMethod() { System.out.println("====initMethod===="); } @PreDestroy public void PreDestroy() { System.out.println("PreDestroy ============="); } // DisposableBean @Override public void destroy() throws Exception { System.out.println("====destroy===="); } // destroyMethod public void destroyMethod() { System.out.println("====destroyMethod===="); } }
配置类:
package qz; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class BeanConfiguration { @Bean(initMethod = "initMethod", destroyMethod = "destroyMethod") public UserService userService() { return new UserService(); } }
编程式IoC如下:
package qz; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; import java.io.IOException; @ComponentScan("qz") public class MainApp { public static void main(String[] args) throws InterruptedException, IOException { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainApp.class); applicationContext.close(); } }
结果:
=============UserService===== ====setBeanName====userService PostConstruct ============= ====afterPropertiesSet==== ====initMethod==== PreDestroy ============= ====destroy==== ====destroyMethod====
3. BeanPostProcessor 的实现
BeanPostProcessor是一个Bean的后置处理器,它可以监听容器触发的事件。将它向IoC容器注册后,容器中管理的Bean具备了接收IoC容器事件回调的能力。接口提供两个方法,一个是postProcessBeforeInitialization 在Bean的初始化之前提供回调入口;还有一个是postProcessAfterInitialization 在Bean的初始化之后提供回调入口。这两个回调都和容器管理Bean的生命周期相关。回调方法的参数都是一样的,分别是Bean的实例化对象和Bean的名字。
如下:
package org.springframework.beans.factory.config; import org.springframework.beans.BeansException; import org.springframework.lang.Nullable; public interface BeanPostProcessor { @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
两个方法的调用都是在doCreateBean方法的initializeBean 方法调用时调用
(1) org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean ‘" + beanName + "‘ to allow for resolving potential circular references"); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } } if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name ‘" + beanName + "‘ has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "‘getBeanNamesForType‘ with the ‘allowEagerInit‘ flag turned off, for example."); } } } } // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
(2) org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; } @Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; } @Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
从上面代码可以看到,这两个Bean后置处理器定义的接口方法,一前一后,围绕着Bean定义的init-method方法调用。
测试如下:
package qz; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.stereotype.Component; /** * @author: 乔利强 * @date: 2021/2/19 15:47 * @description: */ @Component public class MyPostProcessor implements BeanPostProcessor { // Bean的初始化之前提供回调入口 @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if ("userService".equals(beanName)) { System.out.println("====postProcessBeforeInitialization===="); } return bean; } // Bean的初始化之后提供回调入口 @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if ("userService".equals(beanName)) { System.out.println("====postProcessAfterInitialization===="); } return bean; } }
结果:
=============UserService===== ====setBeanName====userService ====postProcessBeforeInitialization==== PostConstruct ============= ====afterPropertiesSet==== ====initMethod==== ====postProcessAfterInitialization==== PreDestroy ============= ====destroy==== ====destroyMethod====
4. Aware的使用
容器管理的Bean一般不需要了解容器的状态和直接使用容器,但在某些情况下,是需要在Bean中直接对IoC容器操作的,这时候就需要设定对容器的感知。SpringIoC容器也提供了该功能,通过特定的Aware接口实现。
在设置Bean的属性之后,调用初始化回调方法之前,Spring会调用sware接口的setter方法。
org.springframework.context.support.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; } }
ApplicationContextAwareProcessor 注入到Spring的时机是在org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory 准备IoC环境时。org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory 如下:
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // Tell the internal bean factory to use the context‘s class loader etc. beanFactory.setBeanClassLoader(getClassLoader()); beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // Configure the bean factory with context callbacks. beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); // BeanFactory interface not registered as resolvable type in a plain factory. // MessageSource registered (and found for autowiring) as a bean. beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // Register early post-processor for detecting inner beans as ApplicationListeners. beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // Detect a LoadTimeWeaver and prepare for weaving, if found. if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } // Register default environment beans. if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }
测试:
package qz; import org.springframework.beans.BeansException; import org.springframework.beans.factory.*; import org.springframework.context.*; import org.springframework.core.io.ResourceLoader; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; //@Component //@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS) //@Lazy public class UserService implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware, ApplicationContextAware, MessageSourceAware, ApplicationEventPublisherAware, ResourceLoaderAware { // 构造 public UserService() { System.out.println("=============UserService====="); } // BeanNameAware====可以在Bean中得到它在IoC容器中的Bean实例名称 @Override public void setBeanName(String name) { System.out.println("====setBeanName====" + name); } // BeanFactoryAware====可以得到Bean所在的IoC容器,从而直接在Bean中石油IoC容器的服务 @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("====beanFactory====" + beanFactory.getClass()); } // ApplicationContextAware====可以在Bean得到Bean所在的应用上下文 @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { System.out.println("====ApplicationContextAware====" + applicationContext.getClass()); } // MessageSourceAware ==== 在Bean中得到消息源 @Override public void setMessageSource(MessageSource messageSource) { System.out.println("====setMessageSource====" + messageSource.getClass()); } // ApplicationEventPublisherAware ==== 在Bean中得到应用上下文的事件发布器,从而可以在Bean中发布应用上下文的事件 @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { System.out.println("====setApplicationEventPublisher====" + applicationEventPublisher.getClass()); } // ResourceLoaderAware ==== 在Bean中得到ResourceLoader,从而在Bean中使用ResourceLoader 加载外部对应的Resource资源 @Override public void setResourceLoader(ResourceLoader resourceLoader) { System.out.println("====setResourceLoader====" + resourceLoader.getClass()); } @PostConstruct public void PostConstruct() { System.out.println("PostConstruct ============="); } // InitializingBean @Override public void afterPropertiesSet() throws Exception { System.out.println("====afterPropertiesSet===="); } // initMethod public void initMethod() { System.out.println("====initMethod===="); } @PreDestroy public void PreDestroy() { System.out.println("PreDestroy ============="); } // DisposableBean @Override public void destroy() throws Exception { System.out.println("====destroy===="); } // destroyMethod public void destroyMethod() { System.out.println("====destroyMethod===="); } }
结果:
=============UserService===== ====setBeanName====userService ====beanFactory====class org.springframework.beans.factory.support.DefaultListableBeanFactory ====setResourceLoader====class org.springframework.context.annotation.AnnotationConfigApplicationContext ====setApplicationEventPublisher====class org.springframework.context.annotation.AnnotationConfigApplicationContext ====setMessageSource====class org.springframework.context.annotation.AnnotationConfigApplicationContext ====ApplicationContextAware====class org.springframework.context.annotation.AnnotationConfigApplicationContext ====postProcessBeforeInitialization==== PostConstruct ============= ====afterPropertiesSet==== ====initMethod==== ====postProcessAfterInitialization==== PreDestroy ============= ====destroy==== ====destroyMethod====
ApplicationContext的初始化与销毁&Bean的生命周期&BeanPostProcessor的使用&Aware使用(四)