Spring Bean 的生命周期
Bean 的生命周期概括起来就是 4 个阶段:
1.主要分为实例化(Instantiation),属性赋值(Populate),初始化(Initialization),销毁(Destruction)这四个大阶段
2.初始化的具体操作,有Aware接口的依赖注入,BeanPostProcessor 在初始化前后的处理以及 InitializingBean和 init-method 的初始化操作;
3.销毁的具体操作,有注册相关销毁回调接口,最后通过DisposableBean 和 destory-method 进行销毁。
下面我们结合代码来直观的看下,在 doCreateBean() 方法中能看到依次执行了这 4 个阶段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | // AbstractAutowireCapableBeanFactory.java protected Object doCreateBean( final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // 1. 实例化 BeanWrapper instanceWrapper = null ; if (instanceWrapper == null ) { instanceWrapper = createBeanInstance(beanName, mbd, args); } Object exposedObject = bean; try { // 2. 属性赋值 populateBean(beanName, mbd, instanceWrapper); // 3. 初始化 exposedObject = initializeBean(beanName, exposedObject, mbd); } // 4. 销毁-注册回调接口 try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } return exposedObject; } |
由于初始化包含了第 3~7步,较复杂,所以我们进到 initializeBean() 方法里具体看下其过程(注释的序号对应图中序号):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | // AbstractAutowireCapableBeanFactory.java protected Object initializeBean( final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { // 3. 检查 Aware 相关接口并设置相关依赖 if (System.getSecurityManager() != null ) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null ; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } // 4. BeanPostProcessor 前置处理 Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } // 5. 若实现 InitializingBean 接口,调用 afterPropertiesSet() 方法 // 6. 若配置自定义的 init-method方法,则执行 try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null ), beanName, "Invocation of init method failed" , ex); } // 7. BeanPostProceesor 后置处理 if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; } |
在 invokInitMethods() 方法中会检查 InitializingBean 接口和 init-method 方法,销毁的过程也与其类似:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | // DisposableBeanAdapter.java public void destroy() { // 9. 若实现 DisposableBean 接口,则执行 destory()方法 if ( this .invokeDisposableBean) { try { if (System.getSecurityManager() != null ) { AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> { ((DisposableBean) this .bean).destroy(); return null ; }, this .acc); } else { ((DisposableBean) this .bean).destroy(); } } } // 10. 若配置自定义的 detory-method 方法,则执行 if ( this .destroyMethod != null ) { invokeCustomDestroyMethod( this .destroyMethod); } else if ( this .destroyMethodName != null ) { Method methodToInvoke = determineDestroyMethod( this .destroyMethodName); if (methodToInvoke != null ) { invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke)); } } } |
从 Spring 的源码我们可以直观的看到其执行过程,而我们记忆其过程便可以从这 4 个阶段出发,实例化、属性赋值、初始化、销毁。其中细节较多的便是初始化,涉及了 Aware、BeanPostProcessor、InitializingBean、init-method 的概念。这些都是 Spring 提供的扩展点,其具体作用将在下一节讲述。
扩展点
- BeanNameAware:注入当前 bean 对应 beanName;
- BeanClassLoaderAware:注入加载当前 bean 的 ClassLoader;
- BeanFactoryAware:注入 当前BeanFactory容器 的引用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // AbstractAutowireCapableBeanFactory.java private void invokeAwareMethods( final String beanName, final Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); } if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory. this ); } } } |
- EnvironmentAware:注入 Enviroment,一般用于获取配置属性;
- EmbeddedValueResolverAware:注入 EmbeddedValueResolver(Spring EL解析器),一般用于参数解析;
- ApplicationContextAware(ResourceLoader、ApplicationEventPublisherAware、MessageSourceAware):注入 ApplicationContext 容器本身。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | // 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); } } |
1 2 3 4 5 6 7 8 9 10 | 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; } } |
- 对于标记接口的实现类,进行自定义处理。例如3.1节中所说的ApplicationContextAwareProcessor,为其注入相应依赖;再举个例子,自定义对实现解密接口的类,将对其属性进行解密处理;
- 为当前对象提供代理实现。例如 Spring AOP 功能,生成对象的代理类,然后返回。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // 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 ; } |
1 2 3 | public interface InitializingBean { void afterPropertiesSet() throws Exception; } |
在 afterPropertiesSet() 方法写初始化逻辑。
指定 init-method 方法,指定初始化方法:
1 2 3 4 5 6 7 | <?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 与上述类似,就不描述了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?