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() 被调用



原文地址:https://www.cnblogs.com/yucongblog/p/11159838.html