您的位置:首页 > 文旅 > 旅游 > 天津建设工程信息网几点更新_微信小程序app下载_百度搜索关键词设置_站长统计网站大全

天津建设工程信息网几点更新_微信小程序app下载_百度搜索关键词设置_站长统计网站大全

2025/9/20 4:58:03 来源:https://blog.csdn.net/weixin_45653328/article/details/142176772  浏览:    关键词:天津建设工程信息网几点更新_微信小程序app下载_百度搜索关键词设置_站长统计网站大全
天津建设工程信息网几点更新_微信小程序app下载_百度搜索关键词设置_站长统计网站大全

上回说到阶段9,现在我们接着往下说

阶段10:所有单例bean初始化完成后阶段

所有单例bean实例化完成之后,spring会回调下面这个接口:

package org.springframework.beans.factory;public interface SmartInitializingSingleton {public void afterSingletonsInstantiated();
}

调用逻辑在下面这个方法中

/**
* 确保所有非lazy的单例都被实例化,同时考虑到FactoryBeans。如果需要,通常在工厂设置结束时调用。
*/
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons

这个方法内部会先触发所有非延迟加载的单例bean初始化,然后从容器中找到类型是SmartInitializingSingleton 的bean,调用他们的 afterSingletonsInstantiated 方法。

来个案例

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("容器启动完毕!");}
}

打印结果

开始启动容器!
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销毁的几种方式

  1. 调用org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#destroyBean
  2. 调用org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons
  3. 调用ApplicationContext中的close方法

Bean销毁阶段会依次执行

  1. 轮询beanPostProcessors列表,如果DestructionAwareBeanPostProcessor这种类型的,会调用其内部的postProcessBeforeDestruction方法
  2. 如果bean实现了org.springframework.beans.factory.DisposableBean接口,会调用这个接口中的destroy方法
  3. 调用bean自定义的销毁方法

DestructionAwareBeanPostProcessor 接口

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;}
}

这个接口有个关键的实现类:

org.springframework.context.annotation.CommonAnnotationBeanPostProcessor

CommonAnnotationBeanPostProcessor#postProcessBeforeDestruction方法中会调用bean中所有标注了@PreDestroy的方法。

再来说一下自定义销毁方法有3种方式
方式1:xml中指定销毁方法

<bean destroy-method="bean中方法名称"/>

方式2:@Bean中指定销毁方法

@Bean(destroyMethod = "初始化的方法")

方式3:api的方式指定销毁方法

this.beanDefinition.setDestroyMethodName(methodName);

初始化方法最终会赋值给下面这个字段

org.springframework.beans.factory.support.AbstractBeanDefinition#destroyMethodName

来个案例

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 {@Overridepublic void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {System.out.println("准备销毁bean:" + beanName);}@Overridepublic boolean requiresDestruction(Object bean) {System.out.println("是否调用。。。。。。。");return true;}
}

测试代码

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()); //@2AbstractBeanDefinition 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();//关闭容器}
}

打印结果

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类(非常重要的类)
image.png

BeanFactory接口
这个我们已经很熟悉了,Bean工厂的顶层接口
DefaultListableBeanFactory类
实现了BeanFactory接口,可以说这个可以是BeanFactory接口真正的唯一实现,内部真正实现了bean生命周期中的所有代码。其他的一些类都是依赖于DefaultListableBeanFactory类,将请求转发给DefaultListableBeanFactory进行bean的处理的。
其他3个类
我们经常用到的就是这3个类:
AnnotationConfigApplicationContext/ClassPathXmlApplicationContext/FileSystemXmlApplicationContext这3个类,他们的主要内部的功能是依赖他的父类AbstractApplicationContext来实现的,所以大家主要看AbstractApplicationContext 这个类。

AbstractApplicationContext类
这个类中有2个比较重要的方法

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列表中

看一下这个方法的源码:

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生命周期完整的流程结束,附上完整的流程图!!完结,我好累
微信图片_20211104122611.jpg

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com