方法springBean Lifecycle in Spring

PS:今天上午,非常郁闷,有很多简略基础的问题搞得我有些迷茫,哎,代码几天不写就忘。目前又不当COO,还是得用心记代码哦!

    

    Bean Lifecycle in Spring

    

    <bean id="person" class="com.meritit.ysjian.spring3learning.beanlife.Person" init-method="myInit" destroy-method="myDestory" scope="singleton" p:id="1001" p:age="125" p:birthday="2013/03/05" />

    @上面这个person Bean的作用域是单例singleton,如果scope=”singleton“不显示指定,也是默认的单例,,如果是通过BeanFactory启动IoC容器时,BeanFactory#getBean方法在调用时才实例化该Bean,将引用返回调用者,然后在缓存池中缓存该Bean实例,Spring继续负责其性命周期的管理。

    <bean id="person" class="com.meritit.ysjian.spring3learning.beanlife.Person" init-method="myInit" destroy-method="myDestory" scope="prototype" p:id="1001" p:age="125" p:birthday="2013/03/05" />

    @该Bean的作用域是prototype,容器启动后,当第一次调用时,Spring容器实例化该Bean并返回给调用者,其后续性命周期由调用者管理,Spring不对其管理,所以prototype作用域destroy-method指定的方法不会执行。

    在Spring中重要的接口:BeanFactory--->ApplicationContext---->WebApplicationContext,BeanFactory和ApplicationContext在前一篇文章介绍过,

    WebApplicationContext wac = (WebApplicationContext) servletContext .getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);

 WebApplicationContext的初始化在web.xml中停止配置,一种是监听器,另一种是Servlet自启动。在前一篇有介绍。

    方法和spring

    

    MyInstantiationAwareBeanPostProcessor,实现了InstantiationAwareBeanPostProcessorAdapter:

    

    public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter { /** * 1.调用者通过getBean向容器请求某个Bean时,实例化Bean前停止调用 */ public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException { // 1.1仅对容器中的person Bean停止处理 if ("person".equals(beanName)) { System.out .println("MyInstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()..."); } return null; } /** * 2.在实例化Bean后调用,对已经实例化的对象停止"梳妆打扮" */ public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { // 2.1进队容器person Bean停止处理 if ("person".equals(beanName)) { System.out .println("MyInstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()..."); } return true; } /** * 3.postProcessAfterInstantiation方法对Bean停止了处理后调用, * 将配置值设置到Bean对应的属性中 */ @Override public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { if ("person".equals(beanName)) { System.out .println("MyInstantiationAwareBeanPostProcessor.postProcessPropertyValues()..."); } return pvs; } }

    @#postProcessBeforeInstantiation方法在调用者通过getBean向容器请求某个Bean时,实例化Bean前停止调用,进而调用Bean的构造方法实例化对象;

    @#postProcessAfterInstantiation方法在在实例化Bean后调用,对已经实例化的对象停止"梳妆打扮";

    /** * 自定义Person Bean,实现了Bean级性命接口,管理Bean性命周期的接口 * @author Ysjian * */ public class Person implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean { private int id; private String name; private int age; private Date birthday; public int getId() { return id; } public void setId(int id) { System.out.println("Person.setId()..."); this.id = id; } public int getAge() { return age; } public void setAge(int age) { System.out.println("Person.setAge()..."); this.age = age; } public String getName() { return name; } public void setName(String name) { System.out.println("Person.setName()..."); this.name = name; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { System.out.println("Person.setBirthday()..."); this.birthday = birthday; } private BeanFactory beanFactory; private String beanName; public Person() { System.out.println("constructor is invoked...."); } /** * 1.BeanNameAware接口的方法, * 在Bean的各项属性值设置终了后调用,设置该Bean对应的名称 */ public void setBeanName(String beanName) { System.out.println("Person.setBeanName()...."); this.beanName = beanName; } /** * 2.BeanFactoryAware的接口方法, * 在该Bean的名称设置好之后调用,将该Bean的实例设置到容器中 */ public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("Person.setBeanFactory()..."); this.beanFactory = beanFactory; } /** * 3.InitializingBean的接口方法, * 在后处理器BeanPostProcessor对Bean加工操纵以后调用 */ public void afterPropertiesSet() throws Exception { System.out.println("Person.afterPropertiesSet()...."); } /** * 4.DisposableBean的接口方法, * singleton单例Bean在容器销毁后调用的方法 */ public void destroy() throws Exception { System.out.println("Person.destroy()..."); } /** * 5.通过Bean的init-method指定初始化方法 */ public void myInit(){ System.out.println("Person.myInit()..."); } /** * 6.通过Bean的destroy-method指定初始化方法, * 单例Bean在DisposableBean#destroy调用后调用,释放资源等操纵 */ public void myDestory(){ System.out.println("Person.myDestory()..."); } @Override public String toString() { return "Person [birthday=" + birthday + ", id=" + id + ", name=" + name + "]"; } }

    @#setBeanName是BeanNameAware接口的方法,在Bean的各项属性值设置终了后调用,设置该Bean对应的名称;

    @#setBeanFactory是BeanFactoryAware的接口方法,在该Bean的名称设置好之后调用,将该Bean的实例设置到容器中;

    @#afterPropertiesSet是InitializingBean的接口方法,在后处理器BeanPostProcessor对Bean加工操纵以后调用,所以在这个进程之前有一个Spring级的后处理器BeanPostProcessor做了一次加工;

    

    MyBeanPostProcessor,实现了BeanPostProcessor:

    

    每日一道理
航行者把树比作指引方向的路灯,劳动者把树比作遮风挡雨的雨伞,诗人把树比作笔下的精灵,而我却要把树比作教师,它就是为我们遮风挡雨的伞,指明方向的路灯,打开知识殿堂的金钥匙。

    /** * Spring级的性命周期接口 * @author Ysjian * */ public class MyBeanPostProcessor implements BeanPostProcessor { /** * 该方法可以对Bean停止特别处理,为容器提供对Bean停止后续加工处理的切入点,如AOP等 * @param bean 以后的Bean * @param beanName 以后Bean的配置名 * @return 加工处理后的Bean */ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if ("person".equals(beanName)) { Person person = (Person) bean; if (person.getAge() > 120) { System.out .println("MyBeanPostProcessor.postProcessBeforeInitialization()..."); person.setAge(100); } } return bean; } /** * 2.在init-method属性指定的方法执行后对Bean再一次停止加工处理 * @param bean 以后的Bean * @param beanName 以后Bean的配置名 * @return 加工处理后的Bean */ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if ("person".equals(beanName)) { Person person = (Person) bean; if (person.getName() == null) { System.out .println("MyBeanPostProcessor.postProcessAfterInitialization()..."); person.setName("ysjian"); } } return bean; } }

    @详细说明,代码中注释了;

    public class BeanLifeCycle { public static void main(String[] args) { LifeCycleBeanFactory(); } private static void LifeCycleBeanFactory() { Resource resource = new ClassPathResource("beans.xml"); BeanFactory bf = new XmlBeanFactory(resource); ConfigurableBeanFactory cFactory = (ConfigurableBeanFactory) bf; // 向容器注册MyBeanPostProcessor cFactory.addBeanPostProcessor(new MyBeanPostProcessor()); // 向容器注册MyInstantiationAwareBeanPostProcessor cFactory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor()); Person person1 = bf.getBean("person", Person.class); // 如果bean的scope="singleton",Spring容器继续负责bean的性命周周期,放入缓存池中,为true,否则否则交给用户,结果为false, person1.setName("first ysjian"); Person person2 = bf.getBean("person", Person.class); System.out.println("person1 == person2:" + (person1 == person2)); // 关闭容器 ((XmlBeanFactory) bf).destroySingletons(); } }

    @ConfigurableBeanFactory#addBeanPostProcessor是用来注册我们自定义的后处理器的,这样注册后,才生效。

    @来看看我们的Bean的性命演变结果:

    MyInstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()... constructor is invoked.... MyInstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()... MyInstantiationAwareBeanPostProcessor.postProcessPropertyValues()... Person.setAge()... Person.setBirthday()... Person.setId()... Person.setBeanName().... Person.setBeanFactory()... MyBeanPostProcessor.postProcessBeforeInitialization()... Person.setAge()... Person.afterPropertiesSet().... Person.myInit()... MyBeanPostProcessor.postProcessAfterInitialization()... Person.setName()... Person.setName()... person1 == person2:true Person.destroy()... Person.myDestory()...

    

思考:那么,清楚了Bean在BeanFactory中的一个性命流程之后,我们是不是可以更灵巧的去定制我们须要的功能,如在init-method,destroy-method,注册多个后处理器呢???

    

当然一般的应用,我们不须要存眷Spring容器级别的接口,因为Spring强大的功能大部分能满意我们的开辟了。但要补上一句:

    

在后面要介绍的Spring的AOP功能的实现也关系到了BeanPostProcessor这个接口,所以继续学习中~ ~

    

    3.ApplicationContext中Bean的初始化阅历了一系列进程:

    

    方法和spring

    /** * 自定义工厂后处理器 * @author Ysjian * */ public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { /** * 在getBean之前对配置文件中配置的Bean的信息停止个性化变动 */ public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) throws BeansException { BeanDefinition bd = bf.getBeanDefinition("car"); //变动配置文件的配置信息 bd.getPropertyValues().addPropertyValue("brand", "BMW"); System.out .println("MyBeanFactoryPostProcessor.postProcessBeanFactory()"); } }

    @这个自定义的工厂后处理器就是在getBean之前对配置文件的信息停止个性化变动

    那么如何让它任务呢?这就须要在beanm.xml中停止配置了:

    

    beans.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" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <bean id="person" class="com.meritit.ysjian.spring3learning.beanlife.Person" init-method="myInit" destroy-method="myDestory" scope="singleton" p:id="1001" p:age="125" p:birthday="2013/03/05" /> <bean id="myBeanPostProcessor" class="com.meritit.ysjian.spring3learning.beanfactory.MyBeanPostProcessor" /> <bean id="myBeanFactoryPostProcessor" class="com.meritit.ysjian.spring3learning.context.MyBeanFactoryPostProcessor" /> <bean id="myInstantiationAwareBeanPostProcessor" class="com.meritit.ysjian.spring3learning.beanfactory.MyInstantiationAwareBeanPostProcessor" /> </beans>

    @ApplicationContext只须要在配置文件中定义自定义的后处理器,让后容器启动的时候回自动识别,让后自动注册;

    private static void LifeCycleApplicationContext() { ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml"); Person person1 = ac.getBean("person", Person.class); // 如果bean的scope="singleton",Spring容器继续负责bean的性命周周期,放入缓存池中,为true,否则否则交给用户,结果为false, // person1.setName("first ysjian"); Person person2 = ac.getBean("person", Person.class); System.out.println("person1 == person2:" + (person1 == person2)); System.out.println(person1.getName()+"--------------"); }

    @结果是:ysjian003--------------,就是说我们自定义的工厂后处理器在getBean调用之前将配置文件中没有的name属性设置为ysjian003了,但不常用。

文章结束给大家分享下程序员的一些笑话语录: 腾讯的动作好快,2010年3月5日19时28分58秒,QQ同时在线人数1亿!刚刚看到编辑发布的文章,相差才2分钟,然后连专题页面都做出来了,他们早就预料到了吧?(其实,每人赠送10Q币,轻轻松松上两亿!)

--------------------------------- 原创文章 By
方法和spring
---------------------------------

原文地址:https://www.cnblogs.com/xinyuyuanm/p/3097641.html