Spring Bean的生命周期

本篇文章已同步更新至Github仓库JavaSummary,欢迎star!

1 前言

Bean生命周期描述的是Spring中一个Bean创建过程和销毁过程中所经历的步骤,其中Bean创建过程是重点。

可以简单地将Bean的生命周期分为五个主干流程:

  • 容器启动阶段(严格来讲这个不属于Bean的生命周期)
  • Bean(单例非懒加载)的实例化阶段
  • Bean的属性注入阶段
  • Bean的初始化阶段
  • Bean的销毁阶段

Spring预留了很多的接口,程序员可以在Bean实例化前后、初始化前后写入一些逻辑对Bean进行自定义加工

2 什么是BeanDefinition?

2.1 简介

BeanDefinition表示Bean定义,Spring根据BeanDefinition来创建Bean对象,BeanDefinition有很多的属性用来描述Bean,BeanDefinition是Spring中非常核心的概念。

2.2 BeanDefinition中重要的属性

属性说明
beanClass表示一个bean的类型,比如:UserService.classOrderService.class,Spring在创建Bean的过程中会根据此属性来实例化得到对象
scope表示一个bean的作用域,比如:
scope等于singleton,该bean就是一个单例Bean
scope等于prototype,该bean就是一个原型bean
isLazy表示一个bean是不是需要懒加载
原型bean的isLazy属性不起作用
懒加载的单例bean,会在第一次getBean的时候生成该bean
非懒加载的单例bean,则会在Spring启动过程中直接生成好
dependsOn表示一个bean在创建之前所依赖的其他bean,在一个bean创建之前,它所依赖的这些bean得先全部创建好
primary表示一个bean是主bean,在Spring中一个类型可以有多个bean对象,在进行依赖注入时,如果根据类型找到了多个bean,此时会判断这些bean中是否存在一个主bean,如果存在,则直接将这个bean注入给属性
initMethodName表示一个bean的初始化方法,一个bean的生命周期过程中有一个步骤叫初始化,Spring会在这个步骤中去调用bean的初始化方法,初始化逻辑由程序员自己控制,表示程序员可以自定义逻辑对bean进行加工

@Component、@Controller、@Service、@Repository、@Bean、<bean/>这些都会解析为BeanDefinition

3 什么是BeanFactory?

3.1 简介

BeanFactory是一种“Spring容器”,BeanFactory翻译过来就是Bean工厂,顾名思义,它可以用来创建Bean、获取Bean,BeanFactory是Spring中非常核心的组件。

3.2 BeanDefinition、BeanFactory、Bean对象

BeanFactory将利用BeanDefinition来生成Bean对象,BeanDefinition相当于BeanFactory的原材料,Bean对象就相当于BeanFactory所生产出来的产品。

3.3 BeanFactory的核心子接口和实现类

ListableBeanFactory
    
ConfigurableBeanFactory
    
AutowireCapableBeanFactory
    
AbstractBeanFactory
    
DefaultListableBeanFactory    

DefaultListableBeanFactory的功能:

支持单例Bean、支持Bean别名、支持父子BeanFactory、支持Bean类型转化、支持Bean后置处理、支持FactoryBean、支持自动装配,等等

4 什么是FactoryBean?

FactoryBean是Spring所提供的一种较灵活的创建Bean的方式,可以通过实现FactoryBean接口中的getObject()方法来返回一个对象,这个对象就是最终的Bean对象。

FactoryBean接口中的方法:

Object getObject(); // 返回的是Bean对象
boolean isSingleton(); // 返回的是否是单例Bean对象
Class getObjectType(); // 返回的是Bean对象的类型
@Component("zhouyu")
public class ZhouyuFactoryBean implements FactoryBean {
    @Override
    // Bean对象
    public 0bject get0bject() throws Exception {
    	return new User();
    }
    @Override
   	// Bean对象的类型
    public class<?> get0bjectType() {
    	return User.class;
    }
    @0verride
    // 所定义的Bean是单例还是原型
    public boolean issingleton() {
    	return true;
    }
}

FactoryBean的特殊点

上述代码,实际上对应了两个Bean对象:

1、beanName为"zhouyu",bean对象为getObject方法所返回的User对象。

2、beanName为"&zhouyu",bean对象为ZhouyuFactoryBean类的实例对象。

FactoryBean对象本身也是一个Bean,同时它相当于一个小型工厂,可以生产出另外的Bean。

BeanFactory是一个Spring容器,是一个大型工厂,它可以生产出各种各样的Bean。

FactoryBean机制被广泛的应用在Spring内部和Spring与第三方框架或组件的整合过程中。

5 Bean的生命周期

  1. 根据BeanDefinition信息,实例化对象,通过构造方法反射得到一个实例化对象

  2. 根据BeanDefinition信息,配置Bean的所有属性(将bean的引用注入到bean对应的属性,*可能存在循环依赖问题)

  3. 如果Bean实现了BeanNameAware接口,工厂调用Bean的setBeanName,参数为Bean的Id

  4. 如果Bean实现BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入

  5. 如果Bean实现ApplicationContextAware接口,Spring将调用setApplicationContext()方法,将bean所在的应用上下文的引用传入进来

  6. 如果存在类实现了BeanPostProcessor接口,执行这些实现类的postProcessBeforeInitialization方法,这相当于在Bean初始化之前插入逻辑

  7. 如果Bean实现InitializingBean接口, 执行afterPropertiesSet方法

  8. 如果Bean指定了init-method方法,就会调用该方法。例:<bean init-method="init">

  9. 如果存在类实现了BeanPostProcessor接口,执行这些实现类的postProcessAfterInitialization方法,这相当于在Bean初始化之后插入逻辑

  10. 这个阶段Bean已经可以使用了,scope为singleton的Bean会被缓存在IOC容器中

  11. 如果Bean实现了DisposableBean接口, 在容器销毁的时候执行destroy方法

  12. 如果配置了destory-method方法,就调用该方法。例:<bean destroy-method="customerDestroy">

在这里插入图片描述

6 验证

通过一个实际的例子验证上图

  1. 首先定义一个业务Bean,实现了诸多扩展接口
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;

public class Car implements BeanFactoryAware, BeanNameAware,
        InitializingBean, DisposableBean {
    private String carName;
    private BeanFactory beanFactory;
    private String beanName;

    public Car() {
        System.out.println("Car-bean的构造函数");
    }
    public void setCarName(String carName) {
        System.out.println("Car-bean属性注入");
        this.carName = carName;
    }

    /**
     * BeanFactoryAware接口方法
     * @param beanFactory
     * @throws BeansException
     */
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("BeanFactoryAware#setBeanFactory()");
        this.beanFactory = beanFactory;
    }

    /**
     * BeanNameAware接口方法
     * @param s
     */
    @Override
    public void setBeanName(String s) {
        System.out.println("BeanNameAware#setBeanName()");
        this.beanName = s;
    }

    /**
     * DisposableBean接口方法
     * @throws Exception
     */
    @Override
    public void destroy() throws Exception {
        System.out.println("DisposableBean#destroy()");
    }

    /**
     * InitializingBean接口方法
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean#afterPropertiesSet()");
    }

    public void carInit() {
        System.out.println("<bean>的init-method属性指定的初始化方法");
    }

    public void carDestory() {
        System.out.println("<bean>的destroy-method属性指定的初始化方法");
    }
}
  1. 自定义一个特殊的BeanFactoryPostProcessor类型的Bean
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    public MyBeanFactoryPostProcessor() {
        super();
        System.out.println("MyBeanFactoryPostProcessor构造函数");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        System.out.println("MyBeanFactoryPostProcessor#postProcessBeanFactory()");
    }
}
  1. 自定义一个特殊的InstantiationAwareBeanPostProcessor类型的Bean
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;

import java.beans.PropertyDescriptor;

public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
    public MyInstantiationAwareBeanPostProcessor() {
        super();
        System.out.println("MyInstantiationAwareBeanPostProcessor构造函数");
    }

    /**
     * 接口方法、实例化Bean之前调用
     * @param beanClass
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if ("car".equals(beanName)) {
            System.out.println("MyInstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()");
        }
        return null;
    }

    /**
     * 接口方法、实例化Bean之后调用
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if ("car".equals(beanName)) {
            System.out.println("MyInstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()");
        }
        return true;
    }

    /**
     * 接口方法、设置某个属性时调用
     * @param pvs
     * @param pds
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        if ("car".equals(beanName)) {
            System.out.println("MyInstantiationAwareBeanPostProcessor#postProcessPropertyValues()");
        }
        return pvs;
    }
}
  1. 自定义一个特殊的BeanPostProcessor类型的Bean
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class MyBeanPostProcessor implements BeanPostProcessor {
    public MyBeanPostProcessor() {
        super();
        System.out.println("MyBeanPostProcessor构造函数");
    }

    @Override
    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
        //可以针对指定的Bean做一些操作
        if ("car".equals(s)) {
            System.out.println("MyBeanPostProcessor#postProcessBeforeInitialization()");
        }
        return o;
    }

    @Override
    public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
        if ("car".equals(s)) {
            System.out.println("MyBeanPostProcessor#postProcessAfterInitialization()");
        }
        return o;
    }
}
  1. 将上述1个业务Bean和3个特殊的Bean配置到xml中
    <bean id="beanPostProcessor" class="IoC.beanLifeCycle.MyBeanPostProcessor"/>
    <bean id = "instantiationAwareBeanPostProcessor" class="IoC.beanLifeCycle.MyInstantiationAwareBeanPostProcessor"/>
    <bean id="beanFactoryPostProcessor" class="IoC.beanLifeCycle.MyBeanFactoryPostProcessor"/>
    <bean id="car" class="IoC.beanLifeCycle.Car" init-method="carInit" destroy-method="carDestory"
          scope="singleton" />
  1. 下面来见证下整个流程
public class Main {
    public static void main(String[] args) {
        String xmlPath = "IoC/beanLifeCycle/applicationContext.xml";
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(xmlPath);
        Car car = context.getBean("car", Car.class);
        System.out.println("car: " + car);
        context.destroy();
    }
}
  1. 控制台输出如下
MyBeanFactoryPostProcessor构造函数
MyBeanFactoryPostProcessor#postProcessBeanFactory()
MyBeanPostProcessor构造函数
MyInstantiationAwareBeanPostProcessor构造函数
MyInstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()
Car-bean的构造函数
MyInstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()
MyInstantiationAwareBeanPostProcessor#postProcessPropertyValues()
BeanNameAware.setBeanName()
BeanFactoryAware.setBeanFactory()
MyBeanPostProcessor#postProcessBeforeInitialization()
InitializingBean.afterPropertiesSet()
<bean>的init-method属性指定的初始化方法
MyBeanPostProcessor#postProcessAfterInitialization()
car: IoC.beanLifeCycle.Car@d2cc05a
DisposableBean.destroy()
<bean>的destroy-method属性指定的初始化方法
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xylitolz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值