Spring-Bean的生命周期

普通的Java对象而言,生命周期相对简单,new的时候创建对象,当没有任何引用的时候被垃圾回收机制回收。

而由Spring Ioc容器托管的对象,它们的生命周期完全由容器完全控制。如图:

实例化Bean

实例化Bean时要看是BeanFactory容器还是ApplicationContext容器。

1.BeanFactory容器:当向容器请求一个未初始的bean时,或初始化bean的时候需要注入到另一个尚未初始化的依赖时的容器就会调用creatBean来进行初始化

2.ApplicationContext容器,当容器启动结束后,便实例化所有的bean。

3.容器通过获取BeanDefinition对象中的信息进行实例化。并且这一步仅仅是简单的实例化,并未进行依赖注入

4.实例化对象被包装在BeanWrapper对象中,BeanWrapper提供了设置对象属性的接口,从而避免了使用反射机制设置属性

设置对象属性(依赖注入)

实例化的对象被封装在BeanWrapper对象中,并且此时对象仍然是一个原生的状态,并没有进行依赖注入

随后Spring根据BeanDefinition中的信息进行依赖注入,并且通过BeanWrapper提供的设置属性的接口完成依赖注入

注入Aware接口

随后Spring会检测该对象是否实现了xxxAware接口,并且将相关的实例注入给bean。

此时bean对象已经被正确构造。

BeanNameAware

如果bean实现此接口,spring将bean的id传给setBeanName()方法

BeanFactoryAware

如果bean实现此接口,Spring将调用setBeanFactory方法,将BeanFactory实例传过来

ApplicationContextAware

如果实现此接口,它的setApplicationContext()方法将被调用,将应用上下文的引用传入到bean中;

BeanPostProcessor

该接口提供了两个函数用来对对象在被使用前做一些自定义的处理,此时Bean会被传递进来,可以对bean做任何处理。

前置处理:在Bean实例创建

1.postProcessBeforeInitialzation( Object bean, String beanName )

2.会先于InitialzationBean执行,所有的Aware接口的注入就是在此完成的

后置处理:

1.postProcessAfterInitialzation( Object bean, String beanName)

InitializingBean与init-method

当前置处理完成后就会进入本阶段。

afterPropertiesSet()

这一阶段也可以在bean正式构造完成前增加我们自定义的逻辑,在这一步没办法处理对象本身,只能增加一些额外的逻辑。

若要使用它,我们需要让bean实现该接口,并把要增加的逻辑写在该函数中。然后Spring会在前置处理完成后检测当前bean是否实现了该接口,并执行afterPropertiesSet函数。

当然,Spring为了降低对客户代码的侵入性,给bean的配置提供了init-method属性,该属性指定了在这一阶段需要执行的函数名。Spring便会在初始化阶段执行我们设置的函数。init-method本质上仍然使用了InitializingBean接口。

DisposableBean和destroy-method

和init-method一样,通过给destroy-method指定函数,就可以在bean销毁前执行指定的逻辑。 

实战案例

package lifecycle;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class PersonBean implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean, ApplicationContextAware {
    private String name;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("【属性赋值】 name="+name);
        this.name = name;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("【接口ApplicationContextAware中的setApplicationContext()方法】");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("【接口BeanFactoryAware中的setBeanFactory()方法】");
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("【接口BeanNameAware中的setBeanName()方法】");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("【接口DisposableBean中的destroy()方法】");
    }

    public void customDestroy() throws Exception {
        System.out.println("【自定义destroy-method】");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("【接口InitializingBean中的afterPropertiesSet()方法】初始化阶段");
    }

    public void init() {
        System.out.println("【自定义init-method】");
    }
}
package lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if(bean instanceof PersonBean){
            System.out.println("MyBeanPostProcessor.postProcessBeforeInitialization");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if(bean instanceof PersonBean){
            System.out.println("MyBeanPostProcessor.postProcessAfterInitialization");
        }
        return bean;
    }
}
package lifecycle;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class LifeCycleTest {

    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-lifecycle.xml");
        PersonBean personBean = (PersonBean) applicationContext.getBean("personBean");
        ((ClassPathXmlApplicationContext) applicationContext).destroy();
    }

}
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
       default-autowire="byName">

    <bean id="personBean" class="lifecycle.PersonBean" init-method="init" destroy-method="customDestroy">
        <property name="name" value="hao are you" />
    </bean>

    <bean id="myBeanPostProcessor" class="lifecycle.MyBeanPostProcessor" />
</beans>

实例化->属性赋值->各种Aware接口的依赖(ApplicationContextAware/BeanNameAware/BeanFactoryAware)->执行BeanPostProcessor前置处理器(postProcessBeforeInitialization)->实现InitializingBean(执行AfterPropertiesSet初始化)/自定义init-method->BeanPostProcessor后置处理器(postProcessAfterInitialization)->实现DisposableBean/自定义destroy-method 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

泡^泡

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

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

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

打赏作者

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

抵扣说明:

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

余额充值