Spring注解详解之Bean生命周期详解

Spring注解详解之Bean生命周期详解

​ spring Bean的生命周期,对于spring平时的学习和运用中,都非常常见,而且也是面试的常见问题,整个的生命周期,大致可以分为,bean的创建,属性赋值,初始化,和销毁四个阶段,每个阶段中又可以自定义对bean进行个性化的操作,spring提供了很多接口,来对bean进行自定义操作;

Bean整个生命周期的执行过程

  1. 实例化BeanFactoryPostProcessor的实现类对象
  2. 执行BeanFactoryPostProcessor的postProcessBeanFactory方法
  3. 实例化InstantiationAwareBeanPostProcessor(或BeanPostProcessor)实现类对象
  4. 执行InstantiationAwareBeanPostProcessor对象的postProcessBeforeInstantiation方法
  5. 执行Bean的构造方法,创建对象
  6. 执行InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法
  7. 执行InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法
  8. Bean属性注入
  9. 执行BeanNameAware的setBeanName方法
  10. 执行BeanFactoryAware的setBeanFactory方法
  11. 执行InstantiationAwareBeanPostProcessor的postProcessBeforeInitialization方法
  12. 执行InitializingBean的afterPropertiesSet方法
  13. 执行bean自定义的初始化方法initMethod
  14. InstantiationAwareBeanPostProcessor(或BeanPostProcessor)实现类的postProcessAfterInitialization方法
  15. bean创建并初始化完成,开始执行销毁容器
  16. 执行DiposibleBean的destory方法
  17. 执行bean自定义的destroyMethod方法
  18. 容器关闭完成

**注意:**在第3步中,InstantiationAwareBeanPostProcessor是BeanPostProcessor的子接口,在BeanPostProcessor中只有两个方法postProcessBeforeInitialization(初始化之前执行)和postProcessAfterInitialization(初始化之后执行),而InstantiationAwareBeanPostProcessor中除了包含这两个接口外,还有postProcessBeforeInstantiation(实例化之前执行)和postProcessAfterInstantiation实例化之后执行,如果项目中既有对BeanPostProcessor接口实现,也有InstantiationAwareBeanPostProcessor接口实现的话,(实际情况不需要实现两个接口,只需要实现子接口即可),两个对象的实例化的顺序,会根据配置的顺序决定的

接口方法分类

从上面的整个的执行流程看出,方法和接口比较多,如果死记硬背的话,很容易忘记,可以对接口和方法进行分类

类型方法
Bean自身的方法通过配置指定的初始化方法initMethod,销毁方法destroyMethod和一些自身的方法(比如get/set方法)
Bean级生命周期接口方法BeanNameAware、BeanFactoryAware、InitializingBean、DiposableBean等接口中的方法
容器级生命周期接口方法InstantiationAwareBeanPostProcessor、BeanPostProcessor,BeanFactoryPostProcessor,等后置处理器实现类中重写的方法

通过分类,是不是很容易记忆了哈

下面会通过示例来进一步详细说明,会有更深的理解

示例

1.Bean自身的方法

/*
User类,并制定初始化方法和销毁方法
*/
public class User {
    private String name;
    private int age;

    public User() {
        System.out.println("【构造器】调用User的构造器实例化");
    }

    public void init(){
        System.out.println("【init-method】调用initMethod属性指定的初始化方法");
    }

    public void destory(){
        System.out.println("【destroy-method】调用destroyMethod属性指定的初始化方法");
    }

    public String getName() {
        return name;
    }

    @Value("James")
    public void setName(String name) {
        System.out.println("【注入属性】注入属性name");
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    @Value("5")
    public void setAge(int age) {
        System.out.println("【注入属性】注入属性age");
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

配置类

@Configuration
public class BeanLifeCycleConfiguratin {
    //向容器中注入user,并指定初始方法和销毁方法
    @Bean(initMethod="init",destroyMethod="destory")
    public User user(){
        return new User();
    }
}

测试方法

@Test
public void testLifeCycle1() {
    System.out.println("开始创建容器,,,");
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanLifeCycleConfiguratin.class);
    System.out.println("容器创建完成,,,");
    User user = applicationContext.getBean(User.class);
    System.out.println(user.toString());
    applicationContext.close();
    System.out.println("容器关闭,,,");
}

//输出结果:
开始创建容器,,,
【构造器】调用User的构造器实例化
【注入属性】注入属性name
【注入属性】注入属性age
【init-method】调用initMethod属性指定的初始化方法
容器创建完成,,,
User{name='James', age=5}
【destroy-method】调用destroyMethod属性指定的初始化方法
容器关闭,,,

2.Bean级生命周期接口方法

package com.ming.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.annotation.Value;

/**
 定义Dog类,并实现BeanNameAware、BeanFactoryAware、InitializingBean、DiposableBean接口
 */
public class Dog  implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean {

    private int id;
    private String name;
    private int age;

    private BeanFactory beanFactory;
    private String beanName;

    public String getName() {
        return name;
    }

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("【有参构造器】调用Dog的构造器实例化");
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        System.out.println("【注入属性】注入属性id");
        this.id = id;
    }

    @Value("kitty")
    public void setName(String name) {
        System.out.println("【注入属性】注入属性name");
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    @Value("5")
    public void setAge(int age) {
        System.out.println("【注入属性】注入属性age");
        this.age = age;
    }

    public Dog() {
        System.out.println("【构造器】调用Dog的构造器实例化");
    }

    //这是BeanFactoryAware接口方法
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()");
        this.beanFactory = beanFactory;
    }

    //这是BeanNameAware接口方法
    @Override
    public void setBeanName(String name) {
        System.out.println("【BeanNameAware接口】调用BeanNameAware.setBeanName()"+name);
        this.beanName = name;
    }

    //这是DiposibleBean接口方法
    @Override
    public void destroy() throws Exception {
        System.out.println("【DiposibleBean接口】调用DiposibleBean.destory()");
    }

    //这是InitializingBean接口方法
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("【InitializingBean接口】调用InitializingBean.afterPropertiesSet()");
    }

    public void init(){
        System.out.println("【init-method】调用initMethod属性指定的初始化方法");
    }

    public void destory(){
        System.out.println("【destroy-method】调用destroyMethod属性指定的初始化方法");
    }

    @Override
    public String toString() {
        return "Dog{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

配置类,和上面的保持一样,注入Dog对象

@Configuration
public class BeanLifeCycleConfiguratin {

    @Bean(initMethod="init",destroyMethod="destory")
    public Dog dog(){
        return new Dog();
    }
}

测试方法

@Test
public void testLifeCycle1() {
    System.out.println("开始创建容器,,,");
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanLifeCycleConfiguratin.class);
    System.out.println("容器创建完成,,,");
    Dog dog = applicationContext.getBean(Dog.class);
    System.out.println(dog.toString());
    applicationContext.close();
    System.out.println("容器关闭,,,");
}

//测试输出结果
开始创建容器,,,
【构造器】调用Dog的构造器实例化
【注入属性】注入属性name
【注入属性】注入属性age
【BeanNameAware接口】调用BeanNameAware.setBeanName()dog
【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()
【InitializingBean接口】调用InitializingBean.afterPropertiesSet()
【init-method】调用initMethod属性指定的初始化方法
容器创建完成,,,
Dog{id=0, name='kitty', age=5}
【DiposibleBean接口】调用DiposibleBean.destory()
【destroy-method】调用destroyMethod属性指定的初始化方法
容器关闭,,,

上面的测试结果可以看出,在实现bean级生命接口的执行顺序:

  • Bean的实例化
  • 进行属性注入
  • 执行Bean的Aware方法(BeanNameAware和BeanFactoryAware)
  • 执行InitializingBean.afterPropertiesSet(),属性注入之后,初始化之前调用
  • 执行自定义的初始化方法
  • 容器销毁,执行DiposibleBean.destory()
  • 执行自定义的销毁方法

3.容器级生命周期接口方法

自定义MyInstantiationAwareBeanPostProcessor实现InstantiationAwareBeanPostProcessor实例化包装bean的后置处理器接口(该接口是BeanPostProcessor的子接口)

public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter{

    public MyInstantiationAwareBeanPostProcessor() {
        super();
        System.out.println("这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!");
    }

    //初始化之前调用
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInitialization方法"+beanName);
        return bean;
    }

    //初始化之后调用
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法"+beanName);
        return bean;
    }

    //在实例化之后,属性注入之前执行
    @Override
    public PropertyValues postProcessPropertyValues(
            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法"+beanName);
        return pvs;
    }
	//实例化之前调用
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法"+beanName);
        return null;
    }
	//实例化之后调用
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessor调用postProcessAfterInstantiation方法"+beanName);
        return true;
    }
}

自定义MyBeanFactoryPostProcessor实现BeanFactoryPostProcessor工厂的后置处理器接口

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    public MyBeanFactoryPostProcessor() {
        super();
        System.out.println("这是BeanFactoryPostProcessor实现类构造器!!");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("BeanFactoryPostProcessor调用postProcessBeanFactory方法");
        BeanDefinition dog = beanFactory.getBeanDefinition("dog");
        dog.getPropertyValues().add("id", 1);
    }
}

配置类,引入自定义的两个组件

@Import({MyInstantiationAwareBeanPostProcessor.class,  MyBeanFactoryPostProcessor.class})
@Configuration
public class BeanLifeCycleConfiguratin {
    @Bean(initMethod="init",destroyMethod="destory")
    public Dog dog(){
        return new Dog();
    }
}

测试方法

@Test
public void testLifeCycle1() {
    System.out.println("开始创建容器,,,");
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanLifeCycleConfiguratin.class);
    System.out.println("容器创建完成,,,");
    Dog dog = applicationContext.getBean(Dog.class);
    System.out.println(dog.toString());
    applicationContext.close();
    System.out.println("容器关闭,,,");
}

//测试执行结果:
开始创建容器,,,
这是BeanFactoryPostProcessor实现类构造器!!
BeanFactoryPostProcessor调用postProcessBeanFactory方法
这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!
InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法beanLifeCycleConfiguratin
InstantiationAwareBeanPostProcessor调用postProcessAfterInstantiation方法beanLifeCycleConfiguratin
InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法beanLifeCycleConfiguratin
InstantiationAwareBeanPostProcessor调用postProcessBeforeInitialization方法beanLifeCycleConfiguratin
InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法beanLifeCycleConfiguratin
InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法dog
【构造器】调用Dog的构造器实例化
InstantiationAwareBeanPostProcessor调用postProcessAfterInstantiation方法dog
InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法dog
【注入属性】注入属性name
【注入属性】注入属性age
【注入属性】注入属性id
【BeanNameAware接口】调用BeanNameAware.setBeanName()dog
【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()
InstantiationAwareBeanPostProcessor调用postProcessBeforeInitialization方法dog
【InitializingBean接口】调用InitializingBean.afterPropertiesSet()
【init-method】调用initMethod属性指定的初始化方法
InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法dog
容器创建完成,,,
Dog{id=1, name='kitty', age=5}
【DiposibleBean接口】调用DiposibleBean.destory()
【destroy-method】调用destroyMethod属性指定的初始化方法
容器关闭,,,

上面的执行结果,容器级别的方法,是会对容器中所有的bean都会起作用,(配置类BeanLifeCycleConfiguratin上的注解@Configuration包含@Component也是容器中的bean),在BeanFactoryPostProcessor的postProcessBeanFactory方法中,对dog对的ID属性的注入也成功了,

对比下上面总结的流程,大致执行过程,bean的生命周期就是这样,对于这些接口的作用,可以查看相关文档,流程大致如此!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值