Bean的初始化和生命周期

bean 的生命周期

  • bean 创建—>初始化—>销毁的过程

  • Spring 容器管理 bean 的生命周期

对象创建

  • 单实例:容器启动时创建对象

  • 多实例:获取对象时创建对象

  • 初始化:

    • 对象创建完成 ,并赋值,调用初始化方法
  • 销毁:

    • 单实例:容器关闭时销毁
    • 多实例:容器不会管理该bean,不会调用销毁方法

自定义初始化和销毁方法

1.指定初始化和销毁方法
  • 之前的初始化方法:<bean init-method="" destory-method=""></bean>

  • 基于注解的初始化方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Car {

public Car() {
System.out.println("容器创建完成!");
}

public void init() {
System.out.println("方法被创建了!");
}
public void destory() {
System.out.println("方法被销毁了!");
}

}
1
2
3
4
5
6
7
8
9
10
@Configuration  //告诉spring这是一个配置类
public class MainConfig {

//设置初始化和销毁方法
@Bean(initMethod = "init",destroyMethod = "destroy")
public Car car() {
return new Car();
}

}
2.让Bean实现 InitializingBean接口DisposableBean接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Car implements InitializingBean, DisposableBean {

public Car() {
}

@Override
public void destroy() throws Exception {
System.out.println("销毁方法~");
}

@Override
public void afterPropertiesSet() throws Exception {
System.out.println("初始化方法~");
}
}
3.可以用 JSR250:

@PostConstruct:在bean创建完成并属性复制完成,执行初始化方法

image-20200413170120664

PreDestroy:在容器销毁bean之前通知我们进行销毁工作

image-20200413170249851

1
2
3
4
5
6
7
8
9
@PostConstruct
public void init() {
System.out.println("@PostConstruct");
}

@PreDestroy
public void destroy() {
System.out.println("@PreDestroy");
}
4.BeanPostProcessor
1
2
3
4
5
6
7
8
9
10
11
12
13
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;
}
}

BeanPostProcessor 原理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
遍历容器中的所有 BeanPostProcessor
挨个执行 beforeInitialization
一旦返回 null
return,跳出 for 循环
不会执行后面的 BeanPostProcessor
*/

//给 bean 进行赋值
populateBean(beanName, mbd, instanceWrapper);
//initializeBean
{
//beforeInitialization
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
//执行自定义初始化方法
this.invokeInitMethods(beanName, wrappedBean, mbd);
//afterInitialization
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

Spring底层对 BeanPostProcessor 的使用:

​ bean赋值、注入其他组件、@Autowired、生命周期注解功能、@Async、···

属性赋值:@Value

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Person {

/*
1.基本数值
2.SpEL:#{}
3.${}:取出配置文件中的值(在运行环境变量中的值)
*/

@value("wxs")
private String name;
@value("#{20-2}")
private Integer age;
private String hobby;
}
1
2
3
4
5
6
7
8
9
@Configuration  //告诉spring这是一个配置类
@PropertySource(value={"classpath:/person.properties"})
public class MainConfig {

//给容器注册一个bean,id默认为方法名
public Person person() {
return new Person();
}
}
1
2
#classpath:/person.properties
person.hobby = singJumpRapAndBasketball

环境切换:@Profile

  • @Profile 注解:逻辑组名称,只有当这些Profile被激活的时候,才会将Profile中所对应的Bean注册到Spring容器中。
    • 加了环境标识的bean,只有环境被激活才会被注册到容器中
    • 写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效
    • 没有标注环境标识的bean,在任何环境下都加载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
   @Profile("dev")
public DataSource dataSourceDev(){
...
}

@Profile("test")
public DataSource dataSourceTest(){
...
}

@Profile("prod")
public DataSource dataSourceProd(){
...
}
  • 激活方法:

    1. 使用命令行动态参数: 设置虚拟机参数 -Dspring.profiles.active=test/dev/prod

    2. 1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      //创建ApplicationContext
      AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);

      //设置需要激活的环境
      context.getEnvironment().setDefaultProfiles("test");
      //注册主配置类
      context.register(MainConfig.class);
      //启动刷新容器
      context.refresh();


Spring容器创建原理【源码分析】

Spring 通过AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigOfAOP.class)来创建容器,

我们就进到 AnnotationConfigApplicationContext 中一探究竟!

==注:以下代码均只截取了源码中重要的部分,并不是完整的源码==

image-20200419083939764

重点关注容器的刷新过程!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//refresh() 中调用的主要方法:
public void refresh() {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);

this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();

this.destroyBeans();
this.cancelRefresh(var9);

this.resetCommonCaches();
}

1. prepareRefresh():刷新前的预处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
protected void prepareRefresh() {
//设置容器启动时间
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
//将容器状态切换为激活状态
this.active.set(true);

//初始化一些属性设置(该方法为空,需要子类重写该方法来个性化属性设置方法)
this.initPropertySources();
//校验属性的合法性等
this.getEnvironment().validateRequiredProperties();
//创建集合保存容器中的一些早期事件
this.earlyApplicationEvents = new LinkedHashSet();
}

2. obtainFreshBeanFactory():获取BeanFactory

1
2
3
4
5
6
7
8
9
10
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
/*
刷新BeanFactory:
1.创建对象:this.beanFactory = new DefaultListableBeanFactory();
2.设置id:this.beanFactory.setSerializationId(this.getId());
*/
this.refreshBeanFactory();
//返回刚才 GenericApplicationContext 创建的 BeanFactory 对象
return this.getBeanFactory();
}

3. prepareBeanFactory(beanFactory):BeanFactory的预准备

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
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//设置BeanFactory的类加载器、支持表达式解析器……
beanFactory.setBeanClassLoader(this.getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
//添加BeanPostProcessor(ApplicationContextAwareProcessor)
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.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//添加BeanPostProcessor(ApplicationListenerDetector)
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
//添加编译时的AspectJ支持
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader
(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));

//给BeanFactory中注册一些能用的组件
//environment【ConfigurableEnvironment】
beanFactory.registerSingleton("environment", this.getEnvironment());
//systemProperties【Map<String, Object>】
beanFactory.registerSingleton
("systemProperties", this.getEnvironment().getSystemProperties());
//systemEnvironment【Map<String, Object>】
beanFactory.registerSingleton
("systemEnvironment", this.getEnvironment().getSystemEnvironment());
}

4. postProcessBeanFactory(beanFactory):BeanFactory准备完成后进行的后置处理工作

1
2
3
//子类通过重写这个方法在 BeanFactory 创建并预准备完成以后做进一步的设置
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}

5. invokeBeanFactoryPostProcessors(beanFactory):执行BeanFactoryPostProcessor

BeanFactoryPostProcessor:在 BeanFactory 标准初始化之后执行

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
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {

/*
核心:invokeBeanFactoryPostProcessors:
先执行BeanDefinitionRegistryPostProcessor的方法:
1.获取所有的BeanDefinitionRegistryPostProcessor
postProcessorNames = beanFactory.getBeanNamesForType
(BeanDefinitionRegistryPostProcessor.class, true, false);
2.先看实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor
postProcessor.postProcessBeanDefinitionRegistry(registry);
3.再执行实现了Ordered接口的BeanDefinitionRegistryPostProcessor
postProcessor.postProcessBeanDefinitionRegistry(registry);
4.最后执行没有实现任何顺序接口的BeanDefinitionRegistryPostProcessor

再执行BeanFactoryPostProcessor的方法
1.获取所有的BeanFactoryPostProcessor
postProcessorNames = beanFactory.getBeanNamesForType
(BeanFactoryPostProcessor.class, true, false);
2.先看实现了PriorityOrdered接口的BeanFactoryPostProcessor
postProcessor.postProcessBeanFactory(registry);
3.再执行实现了Ordered接口的BeanFactoryPostProcessor
postProcessor.postProcessBeanFactory(registry);
4.最后执行没有实现任何顺序接口的BeanFactoryPostProcessor
*/
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors
(beanFactory, this.getBeanFactoryPostProcessors());

beanFactory.addBeanPostProcessor
(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader
(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));

}

6. registerBeanPostProcessors(beanFactory):注册 Bean 的后置处理器

1
2
3
4
5
6
7
8
9
10
11
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
/*
1.获取所有的 BeanPostProcessor(后置处理器都默认可以有PriorityOrdered、Ordered)
2.先注册PriorityOrdered接口的BeanPostProcessor
3.再注册实现了Order接口的BeanPostProcessor
4.然后注册没有实现任何优先级接口的BeanPostProcessor
5.再注册MergedBeanDefinitionPostProcessor
6.最终注册一个ApplicationListenerDetector,在Bean创建完成后检查是否是ApplicationListener
*/
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

7. initMessageSource():初始化MessageSource组件(国际化、消息绑定、消息解析)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protected void initMessageSource() {
//1.获取BeanFactory
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
//2.看容器中是否有messageSource类型的组件
// MessageSource:取出国际化配置文件中的某个key值、能按照区域信息获取
if (beanFactory.containsLocalBean("messageSource")) {
//有就直接拿过来用,赋值给messageSource属性
this.messageSource =
(MessageSource)beanFactory.getBean("messageSource", MessageSource.class);
} else {
//没有就创建一个messageSource类型的组件
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(this.getInternalParentMessageSource());
this.messageSource = dms;
//3.把创建好的MessageSource注册在容器中,以后获取国际化配置文件的值时,可以自动注入MessageSource
beanFactory.registerSingleton("messageSource", this.messageSource);
}
}

8. initApplicationEventMulticaster():初始化事件派发器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
protected void initApplicationEventMulticaster() {
//1.获取BeanFactory
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
//2.从BeanFactory中获取applicationEventMulticaster的ApplicationEventMulticaster
if (beanFactory.containsLocalBean("applicationEventMulticaster")) {
this.applicationEventMulticaster = (ApplicationEventMulticaster)beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class);
//3.如果BeanFactory中没有,创建一个SimpleApplicationEventMulticaster
} else {
this.applicationEventMulticaster =
new SimpleApplicationEventMulticaster(beanFactory);
//4.将ApplicationEventMulticaster添加到BeanFactory中,以后其他组件直接自动注入
beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
}
}

9. onRefresh():留给子容器

子类重写该方法,在容器刷新时可以自定义逻辑

10. registerListeners():将项目中的ApplicationListener注册进容器中

1
2
3
4
5
6
7
8
9
protected void registerListeners() {

//1.从容器中拿到所有的ApplicationListener
String[] listenerBeanNames =
this.getBeanNamesForType(ApplicationListener.class, true, false);
//2.将每个监听器添加到事件派发器中
this.getApplicationEventMulticaster().
addApplicationListenerBean(listenerBeanName);
}

11. finishBeanFactoryInitialization(beanFactory):初始化所有剩下的单实例Bean

1
2
3
4
5
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {

//初始化剩下的单实例bean
beanFactory.preInstantiateSingletons();
}

​ **beanFactory.preInstantiateSingletons()**:

  1. 获取容器中所有Bean,依次进行初始化和创建对象

  2. 获取Bean的定义信息 RootBeanDefinition

  3. if(Bean不是抽象的、是单实例的、不是懒加载的)

    1. 判断是否是 FactoryBean / 是否是实现 FactoryBean 的 Bean

    2. 不是工厂Bean,利用getBean() 创建对象 (以后再深挖)

      • getBean()->doGetBean()->getSingleton()(缓存中获取单实例Bean)

        ​ -> getSingleton()->creatBean()->doCreatBean()

        ​ (获取不到就创建Bean)

12. finishRefresh():完成BeanFactory的初始化创建工作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
protected void finishRefresh() {
//1.清楚资源缓存
this.clearResourceCaches();
/*
2.初始化和生命周期有关的处理器
默认从容器中找 lifecycleProcessor 的组件
如果没有就创建一个默认的生命周期组件,加入到容器中
*/
this.initLifecycleProcessor();
//3.拿到前面的生命周期处理器(BeanFactory),回调onRefresh()方法
this.getLifecycleProcessor().onRefresh();
//4.发布容器刷新完成事件
this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));
LiveBeansView.registerApplicationContext(this);
}

13. 总结

  1. Spring容器在启动时,先会保存所有注册进来的Bean的定义信息

    1. XML注册bean:<bean></bean>
    2. 注解注册bean:@Service,@Controller,@Resporties,@Component,@Bean
  2. Spring会在合适的时机创建这些 bean

    1. 用到这个 bean 的时候,利用getBean()创建bean,创建好后保存在容器中
    2. 统一创建剩下所有 bean finishBeanFactoryInitialization()
  3. 后置处理器

    每一个 bean 创建完成后都会使用后置处理器进行处理,来增强 bean 的功能

  4. 事件驱动模型

    ApplicationListener:事件监听

    ApplicationEventMulticaster:事件派发