Spring中Bean的生命周期

什么是Spring Bean的生命周期

        Spring Bean的生命周期是从 Bean 实例化之后,即通过反射创建出对象之后,到Bean成为一个完整对象,最终存储到单例池中,这个过程被称为Spring Bean的生命周期。Spring Bean的生命周期大体上分为四个阶段 

实例化 => 初始化 => 操作使用 => 销毁

Bean生命周期详细

1. Bean的实例化

1.1 方式:

        1,使用类构造器实例化(无参构造函数)

                直接通过Spring工厂返回类的实例对象

        2,使用静态工厂方法实例化(简单工厂模式)

                Spring工厂调用自定义工厂的静态方法返回类的实例对象。

        3,使用实例工厂方法实例化(工厂方法模式)

                Spring工厂调用工厂的普通方法(非静态方法)返回类的实例对象。

1.2 基本流程:

        1.加载注解和xml配置文件,解析获取配置中的每个的信息,封装成一个个的BeanDefinition对象

        2.将BeanDefinition存储在一个名为beanDefinitionMap的Map中;

        3.ApplicationContext底层遍历beanDefinitionMap,创建Bean实例对象,成一个半成品bean

1.3 Bean工厂后处理器

BeanFactoryPostProcessor:

        BeanFactoryPostProcessor是一个接口规范,实现了该接口的类只要交由Spring容器管理的话,那么Spring就会回调该接口的方法,用于对BeanDefinition注册修改的功能。

BeanDefinitionRegistryPostProcessor
BeanFactoryPostProcessor 的子接口 专门用 于 注册BeanDefinition 操作

eg: 

        1.创建实体类user 
public class user  {
    public user() {
        System.out.println("创建了user");
    }
}

        2.创建两个类分别实现BeanFactoryPostProcessor接口和BeanDefinitionRegistryPostProcessor接口

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        System.out.println("进入了postProcessBeanFactory方法");
    }
}
public class MyBeanFactoryPostProcessor2 implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        System.out.println("进入了postProcessBeanDefinitionRegistry方法");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
    }
}

        3.注入

<bean id="mbfpp" class="com.ape.factory.MyBeanFactoryPostProcessor"></bean>
<bean id="mbfpp2" class="com.ape.factory.MyBeanFactoryPostProcessor2"></bean>
<bean id="user"  class="com.ape.bean.user"></bean>

        4.测试

public class test {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applactionContext.xml");
        System.out.println(context.getBean("user"));
    }
}

        5.结果

2. Bean的初始化和销毁

        2.1 属性填充

        BeanDefinition 中有对当前Bean实体的注入信息通过属性propertyValues进行了存储,例如

        Spring在进行属性注入时,会分为如下几种情况:

  • 注入普通属性,String、int或存储基本类型的集合时,直接通过set方法的反射设置进去;
  • 注入单向对象引用属性时,从容器中getBean获取后通过set方法反射设置进去,如果容器中没有,则先创建被注入对象Bean实例(完成整个生命周期)后,在进行注入操作;
  • 注入双向对象引用属性时,就比较复杂了,涉及了循环引用(循环依赖)Spring如何解决循环依赖

2.2 Aware接口

        Aware接口是一种框架辅助属性注入的一种思想,其他框架中也可以看到类似的接口。框架具备高度封装性,我们接触到的一般都是业务代码,一个底层功能API不能轻易的获取到,但是这不意味着永远用不到这些对象,如果用到了, 就可以使用框架提供的类似Aware的接口,让框架给我们注入该对象

2.3 Bean后处理器

BeanPostProcessor

被实例化后,到最终缓存到名为singletonObjects单例池之前,中间会经过Bean的初始化过程,例如:属性的填充、初始方法init的执行等,其中有一个对外进行扩展的点BeanPostProcessor,我们称为Bean后处理。跟上面的 Bean工厂后处理器相似,它也是一个接口,实现了该接口并被容器管理的BeanPostProcessor,会在流程节点上被Spring自动调用。

2.4 销毁

        接口销毁

        当 Bean 不再需要时,会经过清理阶段,如果Bean 实现了 DisposableBean这个接口,会调用其实现的 destroy()方法执行销毁;

        属性销毁

        如果这个 Bean 的 spring 配置中配置了 destroy-method 属性,会自动调用其配置的自定义销毁方法。

eg:

      1. 定义实体类, 实现各种aware接口和DisposableBean, InitializingBean (接口的初始化和销毁)

public class user implements BeanNameAware, ApplicationContextAware, BeanFactoryAware, DisposableBean, InitializingBean {
    private String sname;

    public void setSname(String sname) {
        this.sname = sname;
        System.out.println("属性注入");
    }

    public user() {
        System.out.println("创建user");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("BeanNameAware==="+beanFactory);
    }

    @Override
    public void setBeanName(String s) {
        System.out.println("ApplicationContextAware==="+s);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("BeanFactoryAware==="+applicationContext);
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("接口销毁");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("接口初始化");
    }

    public void dodistory(){
        System.out.println("属性销毁");
    }

    public void doinit(){
        System.out.println("属性初始化");
    }
}

        2.定义类实现BeanPostProcessor

public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("bean后处理器的前置方法");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("bean后处理器的后置方法");
        return bean;
    }
}

        3. 注入

<bean id="user" class="com.ape.bean.user" init-method="doinit" destroy-method="dodistory">
    <property name="sname" value="Mr.li"></property>
</bean>

<bean id="MBPP" class="com.ape.factory.MyBeanPostProcessor"></bean>

        4. 测试

public class test {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext con = new ClassPathXmlApplicationContext("applicationContext.xml");
        con.getBean("user");
        con.close();
    }
}

        5. 结果

总结:

   

1.实例化

        1) 构造器或工厂实例化

        2) 执行Bean工厂后处理器的回调方法

2.初始化

        1)属性填充

        2)实现各种Aware接口

        3)执行BeanPostProcessor的before()方法

        4)执行InitializingBean接口的初始化方法

        5)执行自定义初始化方法init-method

        6)执行BeanPostProcessor的after()方法

3.操作使用

4.销毁

        1)接口销毁

        2)属性销毁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值