• SpringBean的生命周期


    bean的生命周期

    传统的java对象的生命周期很简单。使用new关键字创建一个对象,就可以使用了。当不再需要使用时,由Java虚拟机自动进行回收。

    Spring中bean的生命周期相对要复杂很多。Spring在创建bean的过程中提供了很多扩展点来允许我们自定义bean的创建过程。

    先看下面这张bean的生命周期图
    在这里插入图片描述
    上图截取至 《spring in action 》 这本书。详细的描述了bean在Spring容器中从创建到销毁经历的若干阶段。每一个阶段都可以针对Spring如何管理bean进行个性化定制。

    对上图的流程进行详细的描述:

    1. Spring对bean进行实例化,即创建这个bean的一个对象;
    2. Spring将值和bean的引用注入到bean对应的属性中;
    3. 如果bean实现了BeanNameAware接口,Spring将bean的ID传递给setBeanName()方法;
    4. 如果bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入;
    5. 如果bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext()方法,将bean所在的应用上下文的引用传进来;
    6. 如果bean实现了BeanPostProcesser接口,Spring将调用它们的postProcessBeforeInitialization()方法;
    7. 如果bean实现了InitializingBean接口,Spring将调用它们的afterPropertiesSet()方法。
    8. 如果bean实现了自己的init-method方法,则该方法被调用;
    9. 如果bean实现了BeanPostProcesser接口,Spring将调用它们的postProcessAfterInitialization()方法;
    10. 此时bean已经准备就绪,可以被程序使用,它们将一直驻留在应用上下文中,直到该应用上下文被销毁;
    11. 如果bean实现了DisposableBean 接口,Spring将调用它们的destroy()方法;
    12. 如果bean实现了自己的destroy-method方法,该方法被调用;

    以上就是参考 《spring in action 》 这本书中描述的Spring容器中bean的生命周期过程,简单来说就是 创建-使用-销毁,在创建时你可以实现Spring提供的接口对创建过程进行干预,在销毁时也可以实现Spring提供的接口对销毁过程进行干预。

    验证

    下面编码验证

    1. 编写TestBean类,实现上述接口
    public class TestBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware,InitializingBean,
            DisposableBean {
    
        private BeanFactory factory;
    
        private ApplicationContext applicationContext;
    
        public TestBean(){
            System.out.println("TestBean 类实例化...");
        }
    
        public void doSomething(){
            System.out.println("调用bean对象的业务方法 doSomething...");
        }
    
        @Override
        public void setBeanName(String s) {
            System.out.println("BeanNameAware接口的 setBeanName方法被调用,Bean的名称为:" + s);
        }
    
        @Override
        public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
            this.factory = beanFactory;
            System.out.println("BeanFactoryAware接口的 setBeanFactory方法被调用");
        }
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext = applicationContext;
            System.out.println("ApplicationContextAware接口的 setApplicationContext方法被调用");
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("InitializingBean接口的 afterPropertiesSet方法被调用");
        }
    
        @PostConstruct
        public void postConstruct(){
            System.out.println("自定义的 postConstruct 方法被调用");
        }
    
        @Override
        public void destroy() throws Exception {
            System.out.println("DisposableBean接口的 destroy方法被调用");
        }
    
        @PreDestroy
        public void preDestroy(){
            System.out.println("自定义的 preDestroy 方法被调用");
        }
    
        public void initMethod(){
            System.out.println("自定义的 initMethod 方法被调用");
        }
    
        public void destroyMethod(){
            System.out.println("自定义的 destroyMethod 方法被调用");
        }
    
    • 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
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    1. 编写 BeanPostProcessor 接口实现类
    public class MyBeanPostProcessor implements BeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("postProcessAfterInitialization--实例化的bean对象:"+bean+"\t"+beanName);
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("postProcessAfterInitialization...实例化的bean对象:"+bean+"\t"+beanName);
            return bean;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    1. 编写配置类
    @Configuration
    public class TestConfig{
    
        @Bean
        public MyBeanPostProcessor myBeanPostProcessor(){
            return new MyBeanPostProcessor();
        }
    
        @Bean(initMethod = "initMethod",destroyMethod = "destroyMethod")
        public TestBean testBean(){
            return new TestBean();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1. 编写测试类
    public class TestMain {
    
        public static void main(String[] args) {
            AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(TestConfig.class);
            TestBean testBean = annotationConfigApplicationContext.getBean(TestBean.class);
            testBean.doSomething();
            annotationConfigApplicationContext.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. 执行结果
    TestBean 类实例化...
    BeanNameAware接口的 setBeanName方法被调用,Bean的名称为:testBean
    BeanFactoryAware接口的 setBeanFactory方法被调用
    ApplicationContextAware接口的 setApplicationContext方法被调用
    postProcessBeforeInitialization--实例化的bean对象:com.demo.TestBean@77d67cf3	testBean
    自定义的 postConstruct 方法被调用
    InitializingBean接口的 afterPropertiesSet方法被调用
    自定义的 initMethod 方法被调用
    postProcessAfterInitialization...实例化的bean对象:com.demo.TestBean@77d67cf3	testBean
    调用bean对象的业务方法 doSomething...
    自定义的 preDestroy 方法被调用
    DisposableBean接口的 destroy方法被调用
    自定义的 destroyMethod 方法被调用
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    验证代码中添加了两个注解方法 @PostConstruct、@PreDestroy 这两个方法有时候经常被用来代替initMethod和destroyMethod方法使用

    各接口的作用

    1. BeanNameAware
      该接口的实现方法只是简单的返回当前bean的名称,让当前bean知道它在容器中的名字。
    2. BeanFactoryAware
      该接口的实现方法返回当前容器的BeanFactory对象,可以用来手动注册 Bean。该对象的真实对象类型是 DefaultListableBeanFactory,调用它的 registerBeanDefinition(beanName, beanDefinition)方法可用手动注册Bean到容器中。
    3. ApplicationContextAware
      该接口的实现方法返回当前容器的上下文对象,该对象是比BeanFactory对象更高一级别的容器对象,也可以实现BeanFactory对象的各种功能。如上面的手动注册Bean。
    4. InitializingBean
      该接口的实现方法在bean的属性被填充后调用,即bean被创建完成后执行,然后我们可以在该方法中处理一些需要bean被实例化后才能做的事。比如网络连接,初始化一些资源等。该方法和initMethod方法、@PostConstruc注解方法经常替换使用。
    5. DisposableBean
      该接口的实现方法在bean被销毁的时候调用,经常用来释放一些资料等。通常和 destroyMethod方法、@PreDestroy注解方法替换使用。
    6. BeanPostProcessor
      该接口被称为Bean的后置处理器。有两个方法 postProcessBeforeInitialization()和postProcessAfterInitialization(),这两个方法的参数也一样。Before方法在初始化方法回调之前执行,可进行bean实例属性的填充等操作。After方法在初始化方法回调后执行,可以在该方法中对Bean对象做一些包装工作。

    以上,是我个人的一点浅显理解,有错误或不足之处,请大家指正。

  • 相关阅读:
    命令行 PDF 转换器:::fCoder 2PDF
    数据迁移一致性测试探索与实践
    MySQL—Apache+PHP+MySQL实现网上社区
    Python3 输出格式美化
    vite脚手架简单使用
    方太集团合同档案管理平台,让数字化成果深度利用、可查可验
    RabbitMQ 之 Work Queues 工作队列
    RouterOS上配置VRRP,OpenWRT上编译入keepalived
    【读书笔记】信息架构:超越Web设计-第一章
    HarmonyOS 音视频开发概述
  • 原文地址:https://blog.csdn.net/wu1308156206/article/details/125884382