上回说到阶段9,现在我们接着往下说
阶段10:所有单例bean初始化完成后阶段
所有单例bean实例化完成之后,spring会回调下面这个接口:
java
package org.springframework.beans.factory;
public interface SmartInitializingSingleton {
public void afterSingletonsInstantiated();
}
调用逻辑在下面这个方法中
java
/**
* 确保所有非lazy的单例都被实例化,同时考虑到FactoryBeans。如果需要,通常在工厂设置结束时调用。
*/
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
这个方法内部会先触发所有非延迟加载的单例bean初始化,然后从容器中找到类型是SmartInitializingSingleton 的bean,调用他们的 afterSingletonsInstantiated 方法。
来个案例
java
package com.shiguiwu.springmybatis.spring.lifecycle.allbeaninit;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;
import java.util.Arrays;
/**
* @description: 10所有bean初始化完成
* 注意是非懒加载的bean初始化完成
* @author: stone
* @date: Created by 2021/3/28 13:35
* @version: 1.0.0
* @pakeage: com.shiguiwu.springmybatis.spring.lifecycle.allbeaninit
*/
@ComponentScan
public class AllBeanInitTests {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
// Arrays.stream(context.getBeanDefinitionNames()).forEach(b -> System.out.println(context.getBean(b)));
context.register(AllBeanInitTests.class);
System.out.println("开始启动容器!");
context.refresh();
System.out.println("容器启动完毕!");
}
}
打印结果
java
开始启动容器!
14:00:04.770 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@11438d26
14:00:04.903 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
14:00:05.473 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [G:\workspace\ideaWorkspace\spring-mybatis\target\classes\com\shiguiwu\springmybatis\spring\lifecycle\allbeaninit\Bean1.class]
14:00:05.474 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [G:\workspace\ideaWorkspace\spring-mybatis\target\classes\com\shiguiwu\springmybatis\spring\lifecycle\allbeaninit\Bean2.class]
14:00:05.483 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [G:\workspace\ideaWorkspace\spring-mybatis\target\classes\com\shiguiwu\springmybatis\spring\lifecycle\allbeaninit\MySmartInitializingSingleton.class]
14:00:05.571 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerProcessor'
14:00:05.586 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory'
14:00:05.588 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
14:00:05.591 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
14:00:05.673 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'allBeanInitTests'
14:00:05.683 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'bean1'
14:00:05.683 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'bean2'
14:00:05.684 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'mySmartInitializingSingleton'
SmartInitializingSingleton#afterSingletonsInstantiated========================
容器启动完毕!
阶段11:Bean使用阶段
这个阶段就不说了,调用getBean方法得到了bean之后,大家可以随意使用,任意发挥。
阶段12:Bean销毁阶段
触发bean销毁的几种方式
- 调用org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#destroyBean
- 调用org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons
- 调用ApplicationContext中的close方法
Bean销毁阶段会依次执行
- 轮询beanPostProcessors列表,如果DestructionAwareBeanPostProcessor这种类型的,会调用其内部的postProcessBeforeDestruction方法
- 如果bean实现了org.springframework.beans.factory.DisposableBean接口,会调用这个接口中的destroy方法
- 调用bean自定义的销毁方法
DestructionAwareBeanPostProcessor 接口
java
package org.springframework.beans.factory.config;
import org.springframework.beans.BeansException;
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
//bean销毁前调用的方法
void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
//用来判断bean是否需要触发postProcessBeforeDestruction方法
default boolean requiresDestruction(Object bean) {
return true;
}
}
这个接口有个关键的实现类:
java
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor#postProcessBeforeDestruction方法中会调用bean中所有标注了@PreDestroy的方法。
再来说一下自定义销毁方法有3种方式
方式1:xml中指定销毁方法
xml
<bean destroy-method="bean中方法名称"/>
方式2:@Bean中指定销毁方法
java
@Bean(destroyMethod = "初始化的方法")
方式3:api的方式指定销毁方法
this.beanDefinition.setDestroyMethodName(methodName);
初始化方法最终会赋值给下面这个字段
java
org.springframework.beans.factory.support.AbstractBeanDefinition#destroyMethodName
来个案例
java
package com.shiguiwu.springmybatis.spring.lifecycle.destroy;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
/**
* @description: 销毁时调用的代码
* @author: stone
* @date: Created by 2021/3/28 14:55
* @version: 1.0.0
* @pakeage: com.shiguiwu.springmybatis.spring.lifecycle.destroy
*/
public class MyDestructionAwareBeanPostProcessor implements DestructionAwareBeanPostProcessor {
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
System.out.println("准备销毁bean:" + beanName);
}
@Override
public boolean requiresDestruction(Object bean) {
System.out.println("是否调用。。。。。。。");
return true;
}
}
测试代码
java
package com.shiguiwu.springmybatis.spring.lifecycle.destroy;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
/**
* @description: 12销毁阶段
*
* 1. 调用
* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#destroyB
* ean
* 2. 调用org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons
* 3. 调用ApplicationContext中的close方法
*
* 顺序
* 1. @PreDestroy标注的所有方法
* 2. DisposableBean接口中的destroy()
* 3. 自定义的销毁方法
* @author: stone
* @date: Created by 2021/3/28 13:59
* @version: 1.0.0
* @pakeage: com.shiguiwu.springmybatis.spring.lifecycle.destroy
*/
public class DestroyTests {
public static void main(String[] args) {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.addBeanPostProcessor(new MyDestructionAwareBeanPostProcessor());
//将CommonAnnotationBeanPostProcessor加入
factory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor()); //@2
AbstractBeanDefinition definition = BeanDefinitionBuilder.genericBeanDefinition(Integer.class)
.addConstructorArgValue(12)
.getBeanDefinition();
AbstractBeanDefinition definition1 = BeanDefinitionBuilder.genericBeanDefinition(Integer.class)
.addConstructorArgValue(12)
.getBeanDefinition();
AbstractBeanDefinition definition3 = BeanDefinitionBuilder.genericBeanDefinition(A.class)
.getBeanDefinition();
//设置销毁方法
definition3.setDestroyMethodName("destroy1");
factory.registerBeanDefinition("shuzi", definition);
factory.registerBeanDefinition("shuzi1", definition1);
factory.registerBeanDefinition("A", definition3);
//触发所有单列初始化
factory.preInstantiateSingletons();
//销毁一个
factory.destroySingleton("shuzi");
System.out.println("销毁所有的bean");
factory.destroySingletons();
//关闭容器
}
}
打印结果
java
14:29:38.611 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'shuzi'
是否调用。。。。。。。
是否调用。。。。。。。
14:29:38.922 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'shuzi1'
是否调用。。。。。。。
是否调用。。。。。。。
14:29:38.923 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'A'
是否调用。。。。。。。
准备销毁bean:shuzi
销毁所有的bean
准备销毁bean:A
preDestroy()
destroy()
destroy1() 自定义的。。。。。。。。
准备销毁bean:shuzi1
实际上ApplicationContext内部已经将spring内部一些常见的必须的 BeannPostProcessor 自动装配到beanPostProcessors列表中 ,比如我们熟悉的下面的几个
1.org.springframework.context.annotation.CommonAnnotationBeanPostProcessor用来处理@Resource、@PostConstruct、@PreDestroy的
2.org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor用来处理@Autowired、@Value注解
3.org.springframework.context.support.ApplicationContextAwareProcessor
用来回调Bean实现的各种Aware接口
下面来说一个非常非常重要的类,打起精神,一定要注意看。
AbstractApplicationContext类(非常重要的类)
BeanFactory接口
这个我们已经很熟悉了,Bean工厂的顶层接口
DefaultListableBeanFactory类
实现了BeanFactory接口,可以说这个可以是BeanFactory接口真正的唯一实现,内部真正实现了bean生命周期中的所有代码。其他的一些类都是依赖于DefaultListableBeanFactory类,将请求转发给DefaultListableBeanFactory进行bean的处理的。
其他3个类
我们经常用到的就是这3个类:
AnnotationConfigApplicationContext/ClassPathXmlApplicationContext/FileSystemXmlApplicationContext这3个类,他们的主要内部的功能是依赖他的父类AbstractApplicationContext来实现的,所以大家主要看AbstractApplicationContext 这个类。
AbstractApplicationContext类
这个类中有2个比较重要的方法
java
public abstract ConfigurableListableBeanFactory getBeanFactory() throws
IllegalStateException;
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory
beanFactory)
大家是否注意过我们使用 AnnotationConfigApplicationContext 的时候,经常调用 refresh方法 ,这个方法内部就会调用上面这2个方法
第一个方法:getBeanFactory()
返回当前应用上下文中的 ConfigurableListableBeanFactory ,这也是个接口类型的,这个接口有一个唯一的实现类: DefaultListableBeanFactory 。有没有很熟悉,上面说过:DefaultListableBeanFactory是BeanFactory真正的唯一实现。应用上线文中就会使用这个 ConfigurableListableBeanFactory 来操作spring容器。
第二个方法:registerBeanPostProcessors
说的通俗点:这个方法就是向ConfigurableListableBeanFactory中注册BeanPostProcessor,内容会从spring容器中获取所有类型的BeanPostProcessor,将其添加到DefaultListableBeanFactory#beanPostProcessors列表中
看一下这个方法的源码:
java
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
会将请求转发给PostProcessorRegistrationDelegate#registerBeanPostProcessors 。内部比较长,大家可以去看一下源码,这个方法内部主要用到了4个BeanPostProcessor 类型的List集合。
List priorityOrderedPostProcessors = new ArrayList<>();
List orderedPostProcessors
List nonOrderedPostProcessors;
List internalPostProcessors = new ArrayList<>();
先说一下:当到方法的时候,spring容器中已经完成了所有Bean的注册。
spring会从容器中找出所有类型的BeanPostProcessor列表,然后按照下面的规则将其分别放到上面的4个集合中,上面4个集合中的 BeanPostProcessor 会被依次添加到DefaultListableBeanFactory#beanPostProcessors列表中,来看一下4个集合的分别放的是那些BeanPostProcessor
priorityOrderedPostProcessors(指定优先级的BeanPostProcessor)
实现org.springframework.core.PriorityOrdered接口的BeanPostProcessor,但是不包含MergedBeanDefinitionPostProcessor类型的
orderedPostProcessors(指定了顺序的BeanPostProcessor)
实现了org.springframework.core.annotation.Order接口的BeanPostProcessor,但是不包含MergedBeanDefinitionPostProcessor类型的
nonOrderedPostProcessors(未指定顺序的BeanPostProcessor)
上面2中类型置为以及MergedBeanDefinitionPostProcessor之外的internalPostProcessors
MergedBeanDefinitionPostProcessor类型的BeanPostProcessor列表。
大家可以去看一下 CommonAnnotationBeanPostProcessor 和
AutowiredAnnotationBeanPostProcessor ,这两个类都实现了 PriorityOrdered 接口,但是他们也实现了MergedBeanDefinitionPostProcessor 接口,所以最终他们会被丢到
internalPostProcessors 这个集合中,会被放入BeanPostProcessor的最后面。
此致,spring bean生命周期完整的流程结束,附上完整的流程图!!完结,我好累