既然你们都放这个图,那我也放吧:java
Bean 的生命周期归纳起来就是 4 个阶段:web
看什么都没有直接看源代码清楚,来吧,上代码:spring
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.7</version> </dependency>
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { //1-实例化 BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { instanceWrapper = this.createBeanInstance(beanName, mbd, args); } Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } synchronized(mbd.postProcessingLock) { if (!mbd.postProcessed) { try { this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable var17) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17); } mbd.postProcessed = true; } } boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName); if (earlySingletonExposure) { if (this.logger.isTraceEnabled()) { this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } this.addSingletonFactory(beanName, () -> { return this.getEarlyBeanReference(beanName, mbd, bean); }); } Object exposedObject = bean; try { //2-属性赋值 this.populateBean(beanName, mbd, instanceWrapper); //3-初始化 exposedObject = this.initializeBean(beanName, exposedObject, mbd); } catch (Throwable var18) { if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) { throw (BeanCreationException)var18; } throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18); } if (earlySingletonExposure) { Object earlySingletonReference = this.getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) { String[] dependentBeans = this.getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length); String[] var12 = dependentBeans; int var13 = dependentBeans.length; for(int var14 = 0; var14 < var13; ++var14) { String dependentBean = var12[var14]; if (!this.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."); } } } } //4-销毁-注册回调接口 try { this.registerDisposableBeanIfNecessary(beanName, bean, mbd); return exposedObject; } catch (BeanDefinitionValidationException var16) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16); } }
因为初始化包含了第 3~7步,较复杂,因此咱们进到 initializeBean() 方法里具体看下其过程(注释的序号对应图中序号):mvc
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { //3-检查 Aware 相关接口并设置相关依赖 if (System.getSecurityManager() != null) { AccessController.doPrivileged(() -> { //Aware系列接口,主要用于辅助Spring bean访问Spring容器 this.invokeAwareMethods(beanName, bean); return null; }, this.getAccessControlContext()); } else { this.invokeAwareMethods(beanName, bean); } // 4-BeanPostProcessor 前置处理 Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName); } // 5-若实现 InitializingBean 接口,调用 afterPropertiesSet() 方法,这俩个方法都在invokeInitMethods里面 // 6-若配置自定义的 init-method方法,则执行 try { this.invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable var6) { throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6); } // 7-BeanPostProceesor 后置处理 if (mbd == null || !mbd.isSynthetic()) { wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
销毁的过程app
public void destroy() { if (!CollectionUtils.isEmpty(this.beanPostProcessors)) { Iterator var1 = this.beanPostProcessors.iterator(); while(var1.hasNext()) { DestructionAwareBeanPostProcessor processor = (DestructionAwareBeanPostProcessor)var1.next(); processor.postProcessBeforeDestruction(this.bean, this.beanName); } } //// 9-若实现 DisposableBean 接口,则执行 destory()方法 if (this.invokeDisposableBean) { if (logger.isTraceEnabled()) { logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'"); } try { if (System.getSecurityManager() != null) { AccessController.doPrivileged(() -> { ((DisposableBean)this.bean).destroy(); return null; }, this.acc); } else { ((DisposableBean)this.bean).destroy(); } } catch (Throwable var3) { String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'"; if (logger.isDebugEnabled()) { logger.warn(msg, var3); } else { logger.warn(msg + ": " + var3); } } } // 10-若配置自定义的 detory-method 方法,则执行 if (this.destroyMethod != null) { this.invokeCustomDestroyMethod(this.destroyMethod); } else if (this.destroyMethodName != null) { Method methodToInvoke = this.determineDestroyMethod(this.destroyMethodName); if (methodToInvoke != null) { this.invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke)); } } }
在 bean 初始化时会经历几个阶段,首先可使用注解 @PostConstruct
, @PreDestroy
来在 bean 的建立和销毁阶段进行调用:ide
@Component public class AnnotationBean { private final static Logger LOGGER = LoggerFactory.getLogger(AnnotationBean.class); @PostConstruct public void start(){ LOGGER.info("AnnotationBean start"); } @PreDestroy public void destroy(){ LOGGER.info("AnnotationBean destroy"); } }
还能够实现 InitializingBean,DisposableBean
这两个接口,也是在初始化以及销毁阶段调用:post
@Service public class SpringLifeCycleService implements InitializingBean,DisposableBean{ private final static Logger LOGGER = LoggerFactory.getLogger(SpringLifeCycleService.class); @Override public void afterPropertiesSet() throws Exception { LOGGER.info("SpringLifeCycleService start"); } @Override public void destroy() throws Exception { LOGGER.info("SpringLifeCycleService destroy"); } }
也能够自定义方法用于在初始化、销毁阶段调用:this
@Configuration public class LifeCycleConfig { @Bean(initMethod = "start", destroyMethod = "destroy") public SpringLifeCycle create(){ SpringLifeCycle springLifeCycle = new SpringLifeCycle() ; return springLifeCycle ; } } public class SpringLifeCycle{ private final static Logger LOGGER = LoggerFactory.getLogger(SpringLifeCycle.class); public void start(){ LOGGER.info("SpringLifeCycle start"); } public void destroy(){ LOGGER.info("SpringLifeCycle destroy"); } }
以上是在 SpringBoot 中能够这样配置,若是是原始的基于 XML 也是可使用:代理
<bean class="com.crossoverjie.spring.SpringLifeCycle" init-method="start" destroy-method="destroy"> </bean>
若 Spring 检测到 bean 实现了 Aware 接口,则会为其注入相应的依赖。因此经过让bean 实现 Aware 接口,则能在 bean 中得到相应的 Spring 容器资源。rest
Spring 中提供的 Aware 接口有:
其代码实现以下:
// AbstractAutowireCapableBeanFactory.java 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 = this.getBeanClassLoader(); if (bcl != null) { ((BeanClassLoaderAware)bean).setBeanClassLoader(bcl); } } if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware)bean).setBeanFactory(this); } } }
以上是针对 BeanFactory 类型的容器,而对于 ApplicationContext 类型的容器,也提供了 Aware 接口,只不过这些 Aware 接口的注入实现,是经过 BeanPostProcessor 的方式注入的,但其做用还是注入依赖。
其代码实现以下:
// ApplicationContextAwareProcessor.java private void invokeAwareInterfaces(Object bean) { 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); } }
实现 Aware 接口
例子:
@Component public class SpringLifeCycleAware implements ApplicationContextAware { private final static Logger LOGGER = LoggerFactory.getLogger(SpringLifeCycleAware.class); private ApplicationContext applicationContext ; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext ; LOGGER.info("SpringLifeCycleAware start"); } }
实现 BeanPostProcessor 接口,Spring 中全部 bean 在作初始化时都会调用该接口中的两个方法,能够用于对一些特殊的 bean 进行处理:
public interface BeanPostProcessor { // 初始化前置处理 default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } // 初始化后置处理 default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
经常使用场景有:
例如 Spring AOP 功能,生成对象的代理类,而后返回。
// AbstractAutoProxyCreator.java public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) { TargetSource targetSource = getCustomTargetSource(beanClass, beanName); if (targetSource != null) { if (StringUtils.hasLength(beanName)) { this.targetSourcedBeans.add(beanName); } Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); // 返回代理类 return proxy; } return null; }
例子:
@Component public class SpringLifeCycleProcessor implements BeanPostProcessor { private final static Logger LOGGER = LoggerFactory.getLogger(SpringLifeCycleProcessor.class); /** * 预初始化 初始化以前调用 * @param bean * @param beanName * @return * @throws BeansException */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if ("annotationBean".equals(beanName)){ LOGGER.info("SpringLifeCycleProcessor start beanName={}",beanName); } return bean; } /** * 后初始化 bean 初始化完成调用 * @param bean * @param beanName * @return * @throws BeansException */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if ("annotationBean".equals(beanName)){ LOGGER.info("SpringLifeCycleProcessor end beanName={}",beanName); } return bean; } } //结果 结果: 00:40:24.856 [restartedMain] INFO c.c.s.p.SpringLifeCycleProcessor - SpringLifeCycleProcessor start beanName=annotationBean 结果: 00:40:24.860 [restartedMain] INFO c.c.spring.annotation.AnnotationBean - AnnotationBean start 结果: 00:40:24.861 [restartedMain] INFO c.c.s.p.SpringLifeCycleProcessor - SpringLifeCycleProcessor end beanName=annotationBean 结果: 00:40:24.864 [restartedMain] INFO c.c.s.aware.SpringLifeCycleAware - SpringLifeCycleAware start 结果: 00:40:24.867 [restartedMain] INFO c.c.s.service.SpringLifeCycleService - SpringLifeCycleService start 结果: 00:40:24.887 [restartedMain] INFO c.c.spring.SpringLifeCycle - SpringLifeCycle start 结果: 00:40:25.062 [restartedMain] INFO o.s.b.d.a.OptionalLiveReloadServer - LiveReload server is running on port 35729 结果: 00:40:25.122 [restartedMain] INFO o.s.j.e.a.AnnotationMBeanExporter - Registering beans for JMX exposure on startup 结果: 00:40:25.140 [restartedMain] INFO com.crossoverjie.Application - Started Application in 2.309 seconds (JVM running for 3.681) 结果: 00:40:25.143 [restartedMain] INFO com.crossoverjie.Application - start ok! 结果: 00:40:25.153 [Thread-8] INFO o.s.c.a.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@3913adad: startup date [Wed Mar 21 00:40:23 CST 2018]; root of context hierarchy 结果: 00:40:25.155 [Thread-8] INFO o.s.j.e.a.AnnotationMBeanExporter - Unregistering JMX-exposed beans on shutdown 结果: 00:40:25.156 [Thread-8] INFO c.c.spring.SpringLifeCycle - SpringLifeCycle destroy 结果: 00:40:25.156 [Thread-8] INFO c.c.s.service.SpringLifeCycleService - SpringLifeCycleService destroy 结果: 00:40:25.156 [Thread-8] INFO c.c.spring.annotation.AnnotationBean - AnnotationBean destroy
直到 Spring 上下文销毁时则会调用自定义的销毁方法以及实现了 DisposableBean
的 destroy()
方法。
InitializingBean 和 init-method 是 Spring 为 bean 初始化提供的扩展点。
InitializingBean接口 的定义以下:
public interface InitializingBean { void afterPropertiesSet() throws Exception; }
在 afterPropertiesSet() 方法写初始化逻辑。
指定 init-method 方法,指定初始化方法:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="demo" class="com.chaycao.Demo" init-method="init()"/> </beans>
DisposableBean 和 destory-method 与上述相似,就不描述了。
最后总结下如何记忆 Spring Bean 的生命周期:
详情请见: