• Spring Bean的生命周期


    Spring自带了两种不同的类型的容器。

    两种容器的的bean生命周期略有不同 ​

    1:bean工厂(由org.springframework.beans.factory.BeanFactory接口定义)是最简单的容器,提供基本的DI 支持。 ​

    2:应用上下文(由org.springframework.context.ApplicationContext接口定义),基于BeanFactory构建,

    并提供应用框架级别的服务,例如 从属性文件解析文本信息以及发布应用事件给感兴趣的事件监听者。

    ApplicationContext Bean生命周期: 

    1.Spring对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.如果上下文中存在实现了BeanPostProcessor接口的bean,Spring将调用它们的postProcessBeforeInitialization()方法;

    7.如果bean实现了InitializingBean接口,Spring将调用它们的afterPropertiesSet()方法。

    8.如果bean使用init-method声明了初始化方法,该方法被调用;

    9.如果上下文中存在实现了BeanPostProcessor接口的bean,Spring将调用它们的postProcessAfterInitialization()方法;

    经过以上过程之后,就可以正式使用该Bean了,对于scope为singleton的Bean,它们将一直驻留在应用上下文中,直到该应用上下文被销毁;

    而对于scope为prototype的Bean,每次被调用都回new一个对象,而且生命周期也交给调用方管理了,不再是Spring容器进行管理了。

    10. 容器关闭后,如果Bean实现了DisposableBean接口,则会调用该接口的destroy()方法。

    11. 如果Bean配置了destroy-method方法,则会执行destroy-method配置的方法,至此,整个Bean生命周期结束。

    BeanFactory Bean生命周期: 与ApplicationContext相比,有如下几点不同:

    1. BeanFactory容器中,不会调用ApplicationContextAware接口的setApplicationContext()方法。
    2. BeanPostProcessor接口的postProcessBeforeInitialization方法和postProcessAfterInitialization方法不会自动调用,必须自己通过代码手动注册
    3. BeanFactory容器启动的时候,不会去实例化所有bean,包括所有scope为singleton且非延迟加载的bean也是一样,而是在调用的时候去实例化。

    详细代码参阅:https://github.com/yucong/spring-bean

    UserService.java:

    package com.yucong.spring.applicationcontext;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.beans.factory.BeanFactoryAware;
    import org.springframework.beans.factory.BeanNameAware;
    import org.springframework.beans.factory.DisposableBean;
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    
    /**
     * 该类实现了BeanNameAware,BeanFactoryAware,ApplicationContextAware,InitializingBean, DisposableBean五个接口,
     * 并且在applicationContext.xml文件中配置了该Bean的id为userService,
     * 并且配置了init-method和destroy-method,为该Bean配置了属性name为userSercie的值,
     * 然后定义了一个名为MyBeanPostProcessor的bean, 该bean定义类实现了BeanPostProcessor接口
     * 
     * 
     */
    public class UserService implements BeanNameAware, BeanFactoryAware,
            ApplicationContextAware, InitializingBean, DisposableBean {
    
        private String name;
    
        public UserService() {
            System.out.println("1.UserService 被实例化,UserService()构造方法");
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
            System.out.println("2.注入属性,setName() 被调用");
        }
    
        public void setBeanName(String beanName) {
            System.out.println("3.注入beanName,BeanNameAware接口的setBeanName被调用, beanName : " + beanName);
        }
    
        public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
            System.out.println("4.注入beanFactory,BeanFactoryAware接口的setBeanFactory被调用, beanFactory : " + beanFactory);
        }
    
        public void setApplicationContext(ApplicationContext applicationContext)
                throws BeansException {
            System.out.println("5.注入applicationContext,ApplicationContextAware接口的setApplicationContext() 被调用, applicationContext : " + applicationContext);
        }
    
        public void afterPropertiesSet() throws Exception {
            System.out.println("7.InitializingBean接口afterPropertiesSet() 被调用");
        }
    
        public void myInit() {
            System.out.println("8.init-method配置的myInit() 被调用");
        }
    
        public void destroy() throws Exception {
            System.out.println("10.DisposableBean接口的destroy() 被调用");
        }
    
        public void myDestroy() {
            System.out.println("11.destroy-method配置的myDestroy() 被调用");
        }
    
        public String toString() {
            return "UserService[name=" + name + "]";
        }
    }
    MyBeanPostProcessor.java
    package com.yucong.spring.applicationcontext;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    
    public class MyBeanPostProcessor implements BeanPostProcessor {
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("9.MyBeanPostProcessor的postProcessAfterInitialization被调用, beanName : "+ beanName);
            return bean;
        }
    
        /**
         *  实例化、依赖注入完毕,在调用显式的初始化之前完成一些定制的初始化任务
         */
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName)
                throws BeansException {
            System.out.println("6.MyBeanPostProcessor的postProcessBeforeInitialization被调用, beanName : "+ beanName);
            return bean;
        }
    
    }

    测试类:Test.java

    public class Test {
    
    
        public static void main(String[] args) {
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
            @SuppressWarnings("unused")
            UserService userService = (UserService) applicationContext.getBean("userService");
    
            ((ClassPathXmlApplicationContext) applicationContext).close();
        }
    }

    applicationContext.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="userService" class="com.yucong.spring.applicationcontext.UserService"
            init-method="myInit" destroy-method="myDestroy">
            <property name="name" value="张三"></property>
        </bean>
    
        <bean id="myPostProcessor"
            class="com.yucong.spring.applicationcontext.MyBeanPostProcessor"></bean>
    
    </beans> 

    运行结果:

    1.UserService 被实例化,UserService()构造方法
    2.注入属性,setName() 被调用
    3.注入beanName,BeanNameAware接口的setBeanName被调用, beanName : userService
    4.注入beanFactory,BeanFactoryAware接口的setBeanFactory被调用, beanFactory : org.springframework.beans.factory.support.DefaultListableBeanFactory@60addb54: defining beans [userService,myPostProcessor]; root of factory hierarchy
    5.注入applicationContext,ApplicationContextAware接口的setApplicationContext() 被调用, applicationContext : org.springframework.context.support.ClassPathXmlApplicationContext@41906a77: startup date [Tue Jul 09 20:02:38 CST 2019]; root of context hierarchy
    6.MyBeanPostProcessor的postProcessBeforeInitialization被调用, beanName : userService
    7.InitializingBean接口afterPropertiesSet() 被调用
    8.init-method配置的myInit() 被调用
    9.MyBeanPostProcessor的postProcessAfterInitialization被调用, beanName : userService
    10.DisposableBean接口的destroy() 被调用
    11.destroy-method配置的myDestroy() 被调用



  • 相关阅读:
    三大范式
    html 横线的代码
    CSS下拉 菜单3.27第一次
    JS页面三种打开方式及对话框
    函数整理
    3.22整理作业
    for循环,if 练习
    php测试题
    设计模式
    面向对象的三大特性
  • 原文地址:https://www.cnblogs.com/yucongblog/p/11159838.html
Copyright © 2020-2023  润新知