Bean对象的生命周期

 

概述:

      对于Spring框架中的Bean对象的生命周期,从大体上基本可分为以下几个阶段:

1.实例化阶段:

         实例化即指的是IOC容器通过反射机制创建bean对象的过程(默认使用单例模式)。此过程又可被分为以下几个阶段:

   (1)加载通过xml配置文件或注解注入IOC容器内所有的类,并通过BeanDefinitionReader接口中的方法将注入容器中的类对应生成BeanDefinition对象。BeanDefinition对象包含了此类的所有信息。

    (2)将所有生成的BeanDefinition对象(下面称为db对象)一一存入一个叫beanDefinitionMap的集合中。

     (3)遍历此集合,取出所有的db对象,执行Bean工厂的后处理器,通过BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor两个接口的实现类的方法实现db对象类型的修改或注册新的db对象。如下图所示:

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory)
            throws BeansException {
        System.out.println("MyBeanFactoryPostProcessor的postProcessBeanFactory方法");
        //修改
        BeanDefinition beanDefinition=configurableListableBeanFactory.getBeanDefinition("stu");
        beanDefinition.setBeanClassName("com.ape.bean.User");
        //新增
        BeanDefinition beanDefinitions=new RootBeanDefinition();
        beanDefinition.setBeanClassName("com.ape.bean.User");
        DefaultListableBeanFactory defaultListableBeanFactory=(DefaultListableBeanFactory)
                configurableListableBeanFactory;
        defaultListableBeanFactory.registerBeanDefinition("user" ,beanDefinition);

    }

}
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry)
            throws BeansException {
        //修改
        BeanDefinition beanDefinition=beanDefinitionRegistry.getBeanDefinition("stu");
        beanDefinition.setBeanClassName("com.ape.bean.User");
        //新增
        BeanDefinition beanDefinitions=new RootBeanDefinition();
        beanDefinition.setBeanClassName("com.ape.bean.User");

        beanDefinitionRegistry.registerBeanDefinition("user" ,beanDefinition);
    }

    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory)
            throws BeansException {

    }
}

    (4)通过反射机制调用注入容器类的无参构造真正创建出bean对象,但此时创建出的bean对象还不完整,暂存于三级缓存singletonFactories中(如存在循环依赖则根据引用关系将被引用者存于二级缓存earlySingletonObjects中)。此时即完成了bean对象的实例化阶段。

2.初始化阶段:

       在bean对象的初始化阶段主要又可分为以下几个阶段:

    (1)属性赋值阶段:此阶段主要通过注入IOC容器中类的set方法或构造方法完成bean对象的属性赋值(通过XML配置文件和注解的方式写法有所不同)。在xml配置文件中主要通过bean标签中的property子标签实现set注入,通过constructor-arg子标签实现构造方法注入,如下图所示:

    <!--基本类型和String-->
    <bean id="student" class="com.ape.bean.Student">
        <property name="name" value="张三"></property>
        <property name="age" value="18"></property>
    </bean>
   <!--javaBean类型-->
    <bean id="iuserdao" class="com.ape.dao.UserDaoImpl"></bean>
    <bean id="iservice" class="com.ape.service.ServiceImpl">
        <property name="iUserDao" ref="iuserdao"></property>
    </bean>
    <bean id="icotroller" class="com.ape.cotroller.CotrollerImpl">
        <property name="service" ref="iservice"></property>
    </bean>
    <!--复杂类型(集合,数组)-->
    <bean id="teacher" class="com.ape.bean.Teacher">
        <property name="set">
            <set>
                <value>张三</value>
                <value>李四</value>
                <value>王五</value>
            </set>
        </property>
        <property name="list">
            <list>
                <value>英雄联盟</value>
                <value>穿越火线</value>
                <value>DNF</value>
            </list>
        </property>
        <property name="arr">
            <array>
                <value>亚索</value>
                <value>亚托克斯</value>
                <value>菲奥娜</value>
            </array>
        </property>
        <property name="map">
            <map>
                <entry key="放逐之刃" value="锐雯"></entry>
                <entry key="刀锋之影" value="泰隆"></entry>
                <entry key="影流之主" value="劫"></entry>
            </map>
        </property>
        <property name="pro">
            <props>
                <prop key="刀锋意志">艾瑞利亚</prop>
                <prop key="铁铠冥魂">莫德凯撒</prop>
                <prop key="复仇之矛">卡莉斯塔</prop>
            </props>
        </property>
    </bean>
<!--基本类型和String-->
    <bean id="student" class="com.ape.bean.Student">
        <constructor-arg name="name" value="张三"></constructor-arg>
        <constructor-arg name="age" value="18"></constructor-arg>
    </bean>
    <!--javabean类型-->
    <bean id="iuserdao" class="com.ape.dao.UserDaoImpl"></bean>
    <bean id="iservice" class="com.ape.service.ServiceImpl">
        <constructor-arg name="iUserDao" ref="iuserdao"></constructor-arg>
    </bean>
    <bean id="icotroller" class="com.ape.cotroller.CotrollerImpl">
        <constructor-arg name="service" ref="iservice"></constructor-arg>
    </bean>
    <!--构造方法方式不支持复杂类型-->

       对于注解的写法,主要则通过@value实现基本类型的属性赋值,通过@Autowired或@Qualifier和@Resource注解完成复杂类型的装配。如下图所示:

@Component(value = "stu")
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class Student {
    //    @Value("张三")
    @Value("${mess1}")
    private String sname;
    //    @Value("18")
    @Value("${mess2}")
    private int age;
@Service
public class ServiceImpl implements IService{
//    @Autowired
//            @Qualifier(value = "userDaoImpl")
    //@Resource(name="userDaoImpl")
@Autowired
IUserDao userDaoImpl02;
    public void save() {
        System.out.println("service的save方法");
        userDaoImpl02.save();
    }
}

   (2)实现Aware接口:如果注入IOC容器的类实现了某个或多个Aware接口,则会根据实现的接口的回调方法完成一些相关的操作。如下图所示:

public class User implements BeanFactoryAware, BeanNameAware, ApplicationContextAware {
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println(beanFactory);
    }

    public void setBeanName(String s) {
        System.out.println(s);
    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println(applicationContext);
    }
}

           以下是几个常用Aware接口的方法详解:

  ab58b4364f1840049e16559275e5d28a.png

   (3)执行bean的后处理中的Before方法:如果存在BeanPostProcessor接口的实现类,则在执行完Aware接口的方法后执行BeanPostProcessor接口中的Before方法,完成相关操作。如下图所示: 

public class MyProcessor implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("MyProcessor的before方法");
        return bean;
    }

 

   (4)执行bean对象的初始化操作:如果注入IOC容器的类实现了InitializingBean接口,则会执行重写此接口的方法(接口初始化),完成相关操作,如果自定义了初始化方法(属性初始化),则会执行自定义的初始化方法。注意属性初始化方法需要与Spring框架绑定,执行时先执行接口初始化,后执行属性初始化。如下所示:

public class Student implements InitializingBean {
    private String name;
    public Student() {
        System.out.println("学生类创建");
    }

    public void setName(String name) {
        System.out.println("属性填充");
        this.name = name;
    }

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

    (5)执行bean的后处理中的After方法:如果存在BeanPostProcessor接口的实现类,在执行完初始化的相关方法后执行BeanPostProcessor接口中的After方法,如下所示:

public Object postProcessAfterInitialization(Object bean, String beanName) 
            throws BeansException {
        System.out.println("MyProcessor的after方法");
        return bean;
    }

  (6)执行完以上操作后就已经基本上完成了bean对象的整个初始化阶段。此时所有注入IOC容器的类的bean对象均已创建完成,并存入一级缓存singletonObjects中,供调用者获取。

   

3.操作使用阶段:

        在bean对象完成实例化和初始化并存入一级缓存后,即可通过Application接口的getBean()获取需要的bean对象进行操作使用了。

4.销毁阶段:

  bean对象的销毁主要有两种方式:

  (1)通过实现DisposableBean接口实现接口销毁。

  (2)通过自定义销毁方法实现属性销毁(自定义方法需绑定Spring框架)

  (3)如果两个方法都有,则先执行接口销毁,再执行属性销毁。

  如下所示:

public class Teacher implements InitializingBean , DisposableBean {
    private String tname;
    public Teacher() {
        System.out.println("javaBean的实例化");

    }

    public void setTname(String tname) {
        System.out.println("属性复制");
        this.tname = tname;
    }

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

    public void destroy() throws Exception {
        System.out.println("接口销毁");
    }
    public void dodestory(){
        System.out.println("属性销毁");
    }
}

  总结:

   bean对象的整个创建过程如下图所示:

bdcebef8dc4e450d88bf251f234bd57a.png

        注意事项:bean的生命周期只针对于通过单例模式创建出来的bean对象,对于多例模式创建的bean对象而言,生命周期这个概念是没有意义的。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值