美文网首页
bean的生命周期

bean的生命周期

作者: 凉风拂面秋挽月 | 来源:发表于2020-02-28 23:28 被阅读0次

生命周期

bean的一生可以分为以下几个部分
1.如果xml中配置了beanFactoryPostProcessor接口的实现,将调用该实现的postProcessBeanFactory方法(该方法可以修改BeanDefinition)

2.根据BeanDefinition实例化bean对象。(通过构造方法或者工厂方法)

3.设置对象属性。(setter等)(依赖注入)

4.如果Bean实现了BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。(和下面的一条均属于检查Aware接口)

5.如果Bean实现了BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身。

6.如果xml中配置了beanPostProcessor接口的实现,将会将Bean实例传递给Bean的后置处理器的postProcessBeforeInitialization(Object bean, String beanname)方法。

7.如果bean实现了InitializingBean接口,将会调用其方法afterPropertiesSet()方法。

8.如果xml的bean中指定了init-method的方法,将调用该方法实现Bean的初始化方法。

9.如果xml中配置了beanPostProcessor接口的实现,将会将Bean实例传递给Bean的后置处理器的postProcessAfterInitialization(Object bean, String beanname)方法。

10.可以使用Bean了。

11.容器关闭之前,调用Bean的销毁方法。如果xml中配置了destory-method方法,将会被调用。未设置则由ioc容器自动销毁。

放张其他博客的流程图

0930070.png

手写一个例子来说明bean的完整生命周期(更新测试)

配置文件spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 支持Spring注解 -->
    <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
    <!-- 注册一个BeanPostProcessor -->
    <bean id="postProcessor" class="com.test.spring.PostProcessor"/>
    <!-- 注册一个BeanFactoryPostProcessor -->
    <bean id="factoryPostProcessor" class="com.test.spring.FactoryPostProcessor"/>
    <!-- 普通bean -->
    <bean id="beanFactoryPostProcessorTest" class="com.test.spring.BeanFactoryPostProcessorTest">
           <property name="name" value="张三"/>
           <property name="sex" value="男"/>
     </bean>
</beans>

工厂级后置处理器BeanFactoryPostProcessor

package com.test.spring;

import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

public class FactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(
            ConfigurableListableBeanFactory configurableListableBeanFactory)
            throws BeansException {
        System.out.println("******调用了BeanFactoryPostProcessor");
        String[] beanStr = configurableListableBeanFactory
                .getBeanDefinitionNames();
        for (String beanName : beanStr) {
            if ("beanFactoryPostProcessorTest".equals(beanName)) {
                BeanDefinition beanDefinition = configurableListableBeanFactory
                        .getBeanDefinition(beanName);
                MutablePropertyValues m = beanDefinition.getPropertyValues();
                if (m.contains("name")) {
                    m.addPropertyValue("name", "赵四");
                    System.out.println("》》》修改了name属性初始值了");
                }
            }
        }
    }
}

bean级后置处理器BeanPostProcessor

package com.test.spring;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
 * bean后置处理器
 * @author zss
 *
 */
public class PostProcessor implements BeanPostProcessor{

    @Override
    public Object postProcessBeforeInitialization(Object bean,
            String beanName) throws BeansException {
        System.out.println("后置处理器处理bean=【"+beanName+"】开始");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean,
            String beanName) throws BeansException {
        System.out.println("后置处理器处理bean=【"+beanName+"】完毕!");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return bean;
    }
}

bean实例实现了InitializingBean,DisposableBean,BeanNameAware,BeanFactoryAware接口

package com.test.spring;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class BeanFactoryPostProcessorTest implements InitializingBean,DisposableBean,BeanNameAware,BeanFactoryAware {
    private String name;
    private String sex;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public void setBeanFactory(BeanFactory paramBeanFactory)
            throws BeansException {
        System.out.println("》》》调用了BeanFactoryAware的setBeanFactory方法了");
    }

    @Override
    public void setBeanName(String paramString) {
        System.out.println("》》》调用了BeanNameAware的setBeanName方法了");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("》》》调用了DisposableBean的destroy方法了");        
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("》》》调用了Initailization的afterPropertiesSet方法了");
    }

    @Override
    public String toString() {
        return "BeanFactoryPostProcessorTest [name=" + name + ", sex=" + sex
                + "]";
    }
}

测试运行

package com.test.spring;

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class T {
    ApplicationContext applicationcontext=null;
    @Before
    public void before() {
        System.out.println("》》》Spring ApplicationContext容器开始初始化了......");
        applicationcontext= new ClassPathXmlApplicationContext(new String[]{"spring-service.xml"});
        System.out.println("》》》Spring ApplicationContext容器初始化完毕了......");
    }
    @Test
    public void  test() {
        //BeanLifecycle beanLifecycle =applicationcontext.getBean("beanLifecycle",BeanLifecycle.class);
        BeanFactoryPostProcessorTest beanFactoryPostProcessorTest=applicationcontext.getBean(BeanFactoryPostProcessorTest.class);
        System.out.println(beanFactoryPostProcessorTest.toString());
    }
}

运行结果

》》》Spring ApplicationContext容器开始初始化了......
2017-03-20 14:36:10  INFO:ClassPathXmlApplicationContext-Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@17ad352e: startup date [Mon Mar 20 14:36:10 CST 2017]; root of context hierarchy
2017-03-20 14:36:10  INFO:XmlBeanDefinitionReader-Loading XML bean definitions from class path resource [spring-service.xml]
******调用了BeanFactoryPostProcessor
》》》修改了name属性初始值了
》》》调用了BeanNameAware的setBeanName方法了
》》》调用了BeanFactoryAware的setBeanFactory方法了
后置处理器处理bean=【beanFactoryPostProcessorTest】开始
后置处理器开始调用了
》》》调用了Initailization的afterPropertiesSet方法了
后置处理器处理bean=【beanFactoryPostProcessorTest】完毕!
后置处理器调用结束了
》》》Spring ApplicationContext容器初始化完毕了......
BeanFactoryPostProcessorTest [name=赵四, sex=男]

原测试

public class Student implements BeanNameAware {
    private String name;
    //无参构造方法
    public Student() {
        super();
    }
    /** 设置对象属性
     * @param name the name to set
     */
    public void setName(String name) {
        System.out.println("设置对象属性setName()..");
        this.name = name;
    }
    //Bean的初始化方法
    public void initStudent() {
        System.out.println("Student这个Bean:初始化");
    }
    //Bean的销毁方法
    public void destroyStudent() {
        System.out.println("Student这个Bean:销毁");
    }
    //Bean的使用
    public void play() {
        System.out.println("Student这个Bean:使用");
    }
    /* 重写toString
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return "Student [name = " + name + "]";
    }

    //调用BeanNameAware的setBeanName()
    //传递Bean的ID。
    @Override
    public void setBeanName(String name) {
        System.out.println("调用BeanNameAware的setBeanName()..." ); 
    }
    
}
public class MyBeanPostProcessor implements BeanPostProcessor {
    //对初始化之后的Bean进行处理
    //参数:bean:即将初始化的bean
    //参数:beanname:bean的名称
    //返回值:返回给用户的那个bean,可以修改bean也可以返回一个新的bean
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanname) throws BeansException {
        Student stu = null;
        System.out.println("对初始化之后的Bean进行处理,将Bean的成员变量的值修改了");
        if("name".equals(beanname) || bean instanceof Student) {
            stu = (Student) bean;
            stu.setName("Jack");
        }
        return stu;
    }
    //对初始化之前的Bean进行处理(这里的初始化不是jvm那个,这个初始化是在配置文件里手动指定的)
    //参数:bean:即将初始化的bean
    //参数:beanname:bean的名称
    //返回值:返回给用户的那个bean,可以修改bean也可以返回一个新的bean
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanname) throws BeansException {
        System.out.println("对初始化之前的Bean进行处理,此时我的名字"+bean);
        return bean;
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
   <!-- init-method:指定初始化的方法
        destroy-method:指定销毁的方法 -->
        <bean id="student" class="com.xuxiao.cycle.Student" init-method="initStudent" destroy-method="destroyStudent">
        <property name="name" value="xuxiao"></property>
        </bean>
        
        <!-- 配置bean的前/后置处理器,不需要id,IoC容器自动识别是一个BeanPostProcessor -->
        <bean class="com.xuxiao.cycle.MyBeanPostProcessor"></bean> 
</beans>

测试类

public class CycleTest {
    @Test
    public void test() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student = (Student) context.getBean("student");
        //Bean的使用
        student.play();
        System.out.println(student);
        //关闭容器
        ((AbstractApplicationContext) context).close();
    }
}

运行结果:


image.png

相关文章

网友评论

      本文标题:bean的生命周期

      本文链接:https://www.haomeiwen.com/subject/qzmqhhtx.html