Spring Bean的生命周期

简介: Spring Bean的生命周期

Bean 生命周期概念的引入

某一天小陈觉得在这个公司有点厌倦了, 准备悄悄的跑路,于是一边上班,一边准备面试题,一边上班,这天他看到了这样一个面试题Spring Bean的生命周期,有点理解不动,他想到了他的领导,那个技术栈特别宽的领导,于是就找到了领导问: 领导我对一个Spring Bean生命周期这个概念有点不太理解,您有时间的话可以给我讲讲吗?

领导说: 等下,我正在处理一个问题,一会儿,我去找你去。过了十五分钟后,领导就来到了小陈的工位,说道:现在我们来过Spring Bean的生命周期这个概念吧!准备好了吗?小陈点了点头。

领导说道: 首先我们要弄清楚生命周期的含义,生命周期的英文是Life Cycle,简单的说就是Spring 给我们提供的一些扩展接口,如果bean实现了这些这些接口,应用在启动的过程中会回调这些接口的方法。在Spring中一个bean的一生通常就是先创建其对象,然后填充其属性,如果这个Bean实现了Spring 提供的扩展接口,那么在IOC容器加载的时候会依次回调这些方法。这些扩展接口的对应方法的回调顺序如下:

image.png

画完图后领导问道: 这里面哪个单词你熟一些啊, 拿出来讲一下。

小陈心里想领导的这个PPT画的怎么这么熟练,还是接着回答道:我好像只见过ApplicationContext,我刚学Spring 框架的时候,用这个ApplicatonContext来获取加载进IOC容器的对象,像下面这样:

public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringBeanConfig.class);
        applicationContext.getBean(StudentService.class);
}

领导点了点头,接着说道:  大多数入门都是从这样的例子开始的,说道这里看着上面的代码你想到了设计模式的哪个模式?

小陈回答道: 这让我想起了简单工厂模式,我给一个标识,由ApplicationContext给我加载对应的对象。

领导点了点头:  ApplicationContext 继承自BeanFactory, 上面的确是使用了简单工厂模式。上面接口中带有Aware的, 都继承自Aware接口。子类将对于父类来说提供的功能更为丰富。setBeanName会从换入实现BeanNameAware接口的Bean Id和Bean名称,也就是说容器在初始化Bean和填充完Bean的属性之后,会回依次回调BeanNameAware、ApplicationContextAware、BeanPostProcessor的postProcessBeforeInitialization、InitializingBean的afterPropertiesSet方法,Bean的init-method方法、BeanPostProcessor的postProcessAfterInitialization的方法。这里要注意BeanNameAware、ApplicationContextAware只会回调依次,每个Bean完成初始化之后都会回调BeanPostProcessor的两个方法。到这里其实就结束了。下面我们写个代码来演示一下上面的顺序:

public class BeanLifeCycleDemo implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean,BeanPostProcessor{
    private MuttonSoupService muttonSoupService;
    public BeanLifeCycleDemo( ) {
        System.out.println("1.构造函数初始化bean");
    }
    @Autowired
    public void setMuttonSoupService(MuttonSoupService muttonSoupService) {
        System.out.println("2.先填充属性-");
        this.muttonSoupService = muttonSoupService;
    }
    public void sayHelloWorld(){
        System.out.println("hello world");
    }
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("----4-- 接着是BeanFactoryAware");
    }
    @Override
    public void setBeanName(String name) {
        System.out.println("3---- name+" + name);
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("----7 afterPropertiesSet");
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("------5 applicationContextAware");
    }
    public void initMethod(){
        System.out.println("6 init-method");
    }
    /**
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("---- postProcessBeforeInitialization"+beanName);
        return bean;
    }
    /**
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("---- postProcessAfterInitialization");
        return bean;
    }
}
@Configuration
public class SpringBeanConfig {
    @Bean(initMethod = "initMethod")
    public BeanLifeCycleDemo beanLifeCycleDemo(){
        return new BeanLifeCycleDemo();
    }
}
@SpringBootTest
class SsmApplicationTests {
    @Autowired
    private BeanLifeCycleDemo beanLifeStyleDemo;
    // 直接运行测试即可
    @Test
    public void test(){
    }
}

输出结果:

image.png

小陈看到了这个结果, 心里有点开心,领导翻车了,于是说道:领导你这个顺序跟上面图的顺序不一样欸。我还有一个问题,这个Bean是永生的吗?

领导淡淡的说道:我是故意演示给你看的, 注意这个BeanPostProcessor,这个接口对应的Bean需要预先加载进入才能实现上面的效果。Spring Bean的加载顺序如下图(下面这张图是网上找的)所示:

image.png

所以我们在写一个BeanPostProcessor的bean就能实现上面的顺序了。至于Bean生命的结束, 其实我是故意考验你的。其实也就是一个接口和一个属性而已. 接口是DisposableBean,属性在@Bean中有个destroyMethod。这两个属性也有替代注解,init-method=@PostConstruct, @PreDestroy=destroyMethod。结合上面的图我们可以大致了解了Spring IOC容器加载Bean的流程,所谓的生命周期在某种程度上可以看成在加载Bean的过程的回调。

小陈说道: 谢谢领导,我感觉我对这个概念理解的更通透了,相对于生命周期,我更喜欢你回调的说法呢。

相关文章
|
4月前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
23天前
|
缓存 Java Spring
实战指南:四种调整 Spring Bean 初始化顺序的方案
本文探讨了如何调整 Spring Boot 中 Bean 的初始化顺序,以满足业务需求。文章通过四种方案进行了详细分析: 1. **方案一 (@Order)**:通过 `@Order` 注解设置 Bean 的初始化顺序,但发现 `@PostConstruct` 会影响顺序。 2. **方案二 (SmartInitializingSingleton)**:在所有单例 Bean 初始化后执行额外的初始化工作,但无法精确控制特定 Bean 的顺序。 3. **方案三 (@DependsOn)**:通过 `@DependsOn` 注解指定 Bean 之间的依赖关系,成功实现顺序控制,但耦合性较高。
实战指南:四种调整 Spring Bean 初始化顺序的方案
|
2月前
|
XML Java 数据格式
Spring从入门到入土(bean的一些子标签及注解的使用)
本文详细介绍了Spring框架中Bean的创建和使用,包括使用XML配置文件中的标签和注解来创建和管理Bean,以及如何通过构造器、Setter方法和属性注入来配置Bean。
75 9
Spring从入门到入土(bean的一些子标签及注解的使用)
|
3月前
|
缓存 安全 Java
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
从底层源码入手,通过代码示例,追踪AnnotationConfigApplicationContext加载配置类、启动Spring容器的整个流程,并对IOC、BeanDefinition、PostProcesser等相关概念进行解释
241 24
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
|
2月前
|
Java 测试技术 Windows
咦!Spring容器里为什么没有我需要的Bean?
【10月更文挑战第11天】项目经理给小菜分配了一个紧急需求,小菜迅速搭建了一个SpringBoot项目并完成了开发。然而,启动测试时发现接口404,原因是控制器包不在默认扫描路径下。通过配置`@ComponentScan`的`basePackages`字段,解决了问题。总结:`@SpringBootApplication`默认只扫描当前包下的组件,需要扫描其他包时需配置`@ComponentScan`。
|
3月前
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
229 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
|
3月前
|
XML Java 数据格式
spring复习02,xml配置管理bean
详细讲解了Spring框架中基于XML配置文件管理bean的各种方式,包括获取bean、依赖注入、特殊值处理、属性赋值、集合类型处理、p命名空间、bean作用域及生命周期和自动装配。
spring复习02,xml配置管理bean
|
2月前
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细解析Spring Bean的生命周期及其核心概念,并深入源码分析。Spring Bean是Spring框架的核心,由容器管理其生命周期。从实例化到销毁,共经历十个阶段,包括属性赋值、接口回调、初始化及销毁等。通过剖析`BeanFactory`、`ApplicationContext`等关键接口与类,帮助你深入了解Spring Bean的管理机制。希望本文能助你更好地掌握Spring Bean生命周期。
98 1
|
2月前
|
Java Spring
获取spring工厂中bean对象的两种方式
获取spring工厂中bean对象的两种方式
45 1
|
2月前
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细介绍了Spring框架中的核心概念——Spring Bean的生命周期,包括实例化、属性赋值、接口回调、初始化、使用及销毁等10个阶段,并深入剖析了相关源码,如`BeanFactory`、`DefaultListableBeanFactory`和`BeanPostProcessor`等关键类与接口。通过理解这些核心组件,读者可以更好地掌握Spring Bean的管理和控制机制。
93 1