(1). Bean 的创立
bean 的创立实际上就是指 构造方法的调用;
singleton(单例)bean
- 容器初始化时会事后调用, 除非标注了 @Lazy 注解指定懒加载 (提早创立);
prototype(原型)bean
- 当第一次调用 getBean 办法时, 才会调用构造方法
(2). Bean 的初始化和销毁 - 4 种办法
bean 的初始化, 指的是在构造方法调用之后, 对象的一些初始化操作;
bean 的销毁, 指的是在 spring 容器敞开前, 对 bean 对象做的一些后续解决操作的调用;
Bean 的初始化和销毁有一下几种办法:
(2.1) @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
的属性 指定了初始化和销毁办法:
- initMethod=”init”
- destroyMethod=”close”
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();}
}
能够看到:
- 构造方法会事后调用 (单例 bean);
- 而后 init 办法被调用;
- 最初上下文敞开时, 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- 调用!
(2.2) InitializingBean/DisposableBean 接口;
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:
- 构造方法调用 (singleton 容器事后初始化);
- InitializingBean#afterPropertiesSet 调用;
- 工厂敞开前: DisposableBean#destroy 调用;
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- 调用!
(2.3) @PostConstruct/@PreDestroy 注解 (JSR250);
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:
- 构造方法调用;
- @PostConstruct 标注的办法调用;
- 上下文敞开时; @PreDestroy 标注的办法被调用;
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- 调用!
(2.4) BeanPostProcessor 接口 (作用范围广);
此接口对所有扫描到的 bean 都起作用:
实现: BeanPostProcessor 接口:
- before-init : postProcessBeforeInitialization(Object bean, String beanName)
- after-init: postProcessAfterInitialization(Object bean, String beanName)
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:
扫描范畴: @ComponentScan(“com.niewj.bean”)
包含: 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
=============================
(2.5) bean 的初始化小结
初始化和销毁有四种形式:
1. @Bean 注解指定属性 initMethod/destroyMethod;
2. 一般 bean 实现 InitializingBean/DisposableBean 接口;
3. 一般 bean 办法上标注 @PostConstruct/@PreDestroy 注解;
4. 通用办法: 实现接口 BeanPostProcessor;
(2.6) 问题来了: 4 种形式的优先级程序是如何的?
上实例: 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:
1.BeanPostProcessor#postProcessBeforeInitialization 首先调用;
2.@PostConstruct;
3.InitializingBean 接口实现;
4.@Bean(initMethod)
5.BeanPostProcessor#postProcessAfterInitialization 调用;
6.@PreDestroy
7.Disposable 接口实现
8.@Bean(destroyMethod)
初始化程序: BeanPostProcessor 的 before-init –> @PostConstruct 注解 –> InitializingBean 接口 –> @Bean 注解指定的 initMethod 办法 –>BeanPostProcessor 的 after-init;
destroy 的程序: @PreDestroy 注解 –> DisposableBean 接口 — > @Bean(destroyMethod)
(2.7) 源码剖析:doCreateBean
源码地位:
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
doCreateBean(){...
try {populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
...
}
1. populateBean: 为 bean 属性赋值等操作;
2. initializeBean: (上面时序图中的操作)
// 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()
2.1 applyBeanPostProcessorsBeforeInitialization
2.2 invokeInitMethods
2.3. applyBeanPostProcessorsAfterInitialization
时序图: