bean的创建实际上就是指 构造方法的调用;
singleton(单例)bean
-容器初始化时会预先调用, 除非标注了 @Lazy 注解指定懒加载(延迟创建);
prototype(原型)bean
-当第一次调用 getBean方法时, 才会调用构造方法
bean的初始化, 指的是在构造方法调用之后, 对象的一些初始化操作;
bean的销毁, 指的是在spring容器关闭前, 对bean对象做的一些后续处理操作的调用;
Bean的初始化和销毁有一下几种方法:
initMethod
/ destroyMethod
;
bean: 普通java类, 其中定义了 方法名: init
close
package com.niewj.bean; public class LifeTestBean1 { private String value; public LifeTestBean1(String value){ System.out.println("LifeTestBean1-初始化!"); this.value = value; } public void init(){ System.out.println("LifeTestBean1#init-调用!"); } public void close(){ System.out.println("LifeTestBean1#close-调用!"); } }
Life1Config配置类中: 通过 @Bean
的属性 指定了初始化和销毁方法:
package com.niewj.config; import com.niewj.bean.LifeTestBean1; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class Life1Config { @Bean(value = "lifeBean1", initMethod = "init", destroyMethod = "close") public LifeTestBean1 lifeTestBean(){ return new LifeTestBean1("bean1"); } }
测试用例: testLifecycle
package com.niewj; import com.niewj.bean.LifeTestBean1; import com.niewj.config.Life1Config; import org.junit.Test; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import java.util.stream.Stream; /** * spring生命周期. */ public class LifecycleTest { @Test public void testLifecycle() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Life1Config.class); // 打印spring容器中的 BeanDefinition Stream.of(ctx.getBeanDefinitionNames()).forEach(e-> System.out.println(e)); System.out.println("============================="); LifeTestBean1 bean = ctx.getBean(LifeTestBean1.class); System.out.println(bean); ctx.close(); } }
可以看到:
LifeTestBean1-初始化! LifeTestBean1#init-调用! org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory life1Config lifeBean1 ============================= com.niewj.bean.LifeTestBean1@7d3a22a9 LifeTestBean1#close-调用!
bean: LifeTestBean2 implements InitializingBean, DisposableBean
package com.niewj.bean; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; /** * 实现 InitializingBean && DisposableBean */ public class LifeTestBean2 implements InitializingBean, DisposableBean { private String value; public LifeTestBean2(String value){ System.out.println("LifeTestBean2-初始化!"); this.value = value; } @Override public void destroy() throws Exception { System.out.println("LifeTestBean2#DisposableBean#destroy-调用!"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("LifeTestBean2#InitializingBean#afterPropertiesSet-调用!"); } }
配置类: Life2Config:
package com.niewj.config; import com.niewj.bean.LifeTestBean2; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class Life2Config { @Bean public LifeTestBean2 lifeTestBean(){ return new LifeTestBean2("bean2"); } }
测试用例:
@Test public void testLifecycle2() { // 1. 通过bean实现 InitializingBean和DisposableBean接口 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Life2Config.class); // 打印spring容器中的 BeanDefinition Stream.of(ctx.getBeanDefinitionNames()).forEach(e-> System.out.println(e)); System.out.println("============================="); LifeTestBean2 bean = ctx.getBean(LifeTestBean2.class); System.out.println(bean); ctx.close(); }
output:
LifeTestBean2-初始化! LifeTestBean2#InitializingBean#afterPropertiesSet-调用! org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory life2Config lifeTestBean ============================= com.niewj.bean.LifeTestBean2@7d3a22a9 LifeTestBean2#DisposableBean#destroy-调用!
bean: LifeTestBean3 注解: @PreDestroy
PostConstruct
package com.niewj.bean; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; /** * 通过 JSR250注解 @PostConstruct && @PreDestroy */ public class LifeTestBean3 { private String value; public LifeTestBean3(String value) { System.out.println("LifeTestBean3-初始化!"); this.value = value; } @PreDestroy public void doDestroy() { System.out.println("LifeTestBean3#doDestroy-调用!"); } @PostConstruct public void doInit() { System.out.println("LifeTestBean3#doInit-调用!"); } }
配置类:
package com.niewj.config; import com.niewj.bean.LifeTestBean3; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class Life3Config { @Bean public LifeTestBean3 lifeTestBean() { return new LifeTestBean3("bean3"); } }
测试用例:
@Test public void testLifecycle3() { // 1. 通过 JSR250注解 @PostConstruct && @PreDestroy AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Life3Config.class); // 打印spring容器中的 BeanDefinition Stream.of(ctx.getBeanDefinitionNames()).forEach(e-> System.out.println(e)); System.out.println("============================="); LifeTestBean3 bean = ctx.getBean(LifeTestBean3.class); System.out.println(bean); ctx.close(); }
output:
LifeTestBean3-初始化! LifeTestBean3#doInit-调用! org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory life3Config lifeTestBean ============================= com.niewj.bean.LifeTestBean3@2a32de6c LifeTestBean3#doDestroy-调用!
此接口对所有扫描到的bean都起作用:
实现: BeanPostProcessor 接口:
package com.niewj.bean; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.stereotype.Component; /** * 通过 BeanPostProcessor 接口 */ @Component public class MyBeanPostProcessor implements BeanPostProcessor { public MyBeanPostProcessor() { System.out.println("MyBeanPostProcessor-初始化!"); } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("MyBeanPostProcessor#postProcessBeforeInitialization-调用!->beanName=" + beanName + "; bean=" + bean); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("MyBeanPostProcessor#postProcessAfterInitialization-调用!->beanName=" + beanName + "; bean=" + bean); return bean; } }
com.niewj.bean包下一个普通类:
package com.niewj.bean; import org.springframework.stereotype.Component; /** * 普通bean+@Component */ @Component public class LifeTestBean4 { public LifeTestBean4() { System.out.println("LifeTestBean4-初始化!"); } }
配置类: Life4Config:
包括: LifeTestBean4.java && MyBeanPostProcessor.java
package com.niewj.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan("com.niewj.bean") public class Life4Config { }
用例: 注册配置类: Life4Config
@Test public void testLifecycle4() { // 1. 通过 实现 BeanPostProcesser 接口 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Life4Config.class); // 打印spring容器中的 BeanDefinition Stream.of(ctx.getBeanDefinitionNames()).forEach(e-> System.out.println(e)); System.out.println("============================="); ctx.close(); }
output: 观察控制台:
MyBeanPostProcessor: postProcessBeforeInitialization/postProcessAfterInitialization
LifeTestBean4: postProcessBeforeInitialization/postProcessAfterInitialization
MyBeanPostProcessor-初始化! MyBeanPostProcessor#postProcessBeforeInitialization-调用!->beanName=life4Config; bean=com.niewj.config.Life4Config$$EnhancerBySpringCGLIB$$684530bf@27c86f2d MyBeanPostProcessor#postProcessAfterInitialization-调用!->beanName=life4Config; bean=com.niewj.config.Life4Config$$EnhancerBySpringCGLIB$$684530bf@27c86f2d LifeTestBean4-初始化! MyBeanPostProcessor#postProcessBeforeInitialization-调用!->beanName=lifeTestBean4; bean=com.niewj.bean.LifeTestBean4@197d671 MyBeanPostProcessor#postProcessAfterInitialization-调用!->beanName=lifeTestBean4; bean=com.niewj.bean.LifeTestBean4@197d671 org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory life4Config lifeTestBean4 myBeanPostProcessor =============================
初始化和销毁有四种方式:
上实例: LifeTestBeanAll.java
其中包含:
1.@PostConstruct/@PreDestroy 注解;
2.InitializingBean, DisposableBean接口的实现;
3.@Bean 指定 initMethod/destroyMethod方法;
4.MyBeanPostProcessor实现(在下方);
package com.niewj.bean; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; /** * 普通bean+@Component */ @Component public class LifeTestBeanAll implements InitializingBean, DisposableBean { public LifeTestBeanAll() { System.out.println("LifeTestBeanAll 构造方法调用!"); } @PostConstruct public void postConstruct(){ System.out.println("LifeTestBeanAll#@PostConstruct 调用"); } @PreDestroy public void preDestroy(){ System.out.println("LifeTestBeanAll#@PreDestroy 调用"); } public void init(){ System.out.println("LifeTestBeanAll#@Bean(initMethod) 调用"); } public void close(){ System.out.println("LifeTestBeanAll#@Bean(destroyMethod) 调用"); } @Override public void destroy() throws Exception { System.out.println("LifeTestBeanAll#Disposable 调用~~"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("LifeTestBeanAll#InitializingBean#调用!~"); } }
MyBeanPostProcessor:
package com.niewj.bean; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.stereotype.Component; /** * 通过 BeanPostProcessor 接口 */ @Component public class MyBeanPostProcessor implements BeanPostProcessor { public MyBeanPostProcessor() { System.out.println("MyBeanPostProcessor-初始化!"); } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("MyBeanPostProcessor#postProcessBeforeInitialization-调用!->beanName=" + beanName + "; bean=" + bean); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("MyBeanPostProcessor#postProcessAfterInitialization-调用!->beanName=" + beanName + "; bean=" + bean); return bean; } }
配置类:
package com.niewj.config; import com.niewj.bean.LifeTestBeanAll; import com.niewj.bean.User; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan("com.niewj.bean") public class LifeAllConfig { @Bean(initMethod = "init", destroyMethod = "close") public LifeTestBeanAll lifeTestBeanAll(){ return new LifeTestBeanAll(); } }
测试用例:
@Test public void testLifecycleAll() { // 注释掉 LifeTestBean4#@Component以防干扰 // 1. 通过 实现 BeanPostProcesser 接口 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(LifeAllConfig.class); // 打印spring容器中的 BeanDefinition Stream.of(ctx.getBeanDefinitionNames()).forEach(e-> System.out.println(e)); System.out.println("============================="); ctx.close(); }
output: 关键地方来了:
MyBeanPostProcessor-初始化! MyBeanPostProcessor#postProcessBeforeInitialization-调用!->beanName=lifeAllConfig; bean=com.niewj.config.LifeAllConfig$$EnhancerBySpringCGLIB$$77052e36@3d121db3 MyBeanPostProcessor#postProcessAfterInitialization-调用!->beanName=lifeAllConfig; bean=com.niewj.config.LifeAllConfig$$EnhancerBySpringCGLIB$$77052e36@3d121db3 LifeTestBeanAll 构造方法调用! MyBeanPostProcessor#postProcessBeforeInitialization-调用!->beanName=lifeTestBeanAll; bean=com.niewj.bean.LifeTestBeanAll@6b26e945 LifeTestBeanAll#@PostConstruct 调用 LifeTestBeanAll#InitializingBean#调用!~ LifeTestBeanAll#@Bean(initMethod) 调用 MyBeanPostProcessor#postProcessAfterInitialization-调用!->beanName=lifeTestBeanAll; bean=com.niewj.bean.LifeTestBeanAll@6b26e945 org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory lifeAllConfig lifeTestBeanAll myBeanPostProcessor ============================= LifeTestBeanAll#@PreDestroy 调用 LifeTestBeanAll#Disposable 调用~~ LifeTestBeanAll#@Bean(destroyMethod) 调用
分析整理: 只看 lifeTestBeanAll:
初始化顺序: BeanPostProcessor的before-init --> @PostConstruct注解 --> InitializingBean接口 --> @Bean注解指定的initMethod方法 -->BeanPostProcessor的after-init;
destroy的顺序: @PreDestroy注解 --> DisposableBean接口 -- > @Bean(destroyMethod)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition) 方法流程源码片段: ---方法名: AbstractAutowireCapableBeanFactory#initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) (1). applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName) 1. 遍历并调用BeanPostProcessor#postProcessBeforeInitialization() (2). invokeInitMethods(beanName, wrappedBean, mbd): 1. 调用 InitializingBean接口的 afterPropertiesSet()方法; 2. 调用 invokeCustomInitMethod() --> @Bean(initMethod) 执行! (3). applyBeanPostProcessorsAfterInitialization 1. 调用 postProcessAfterInitialization()
时序图: