Spring Bean 生命周期管理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/littleboyandgirl/article/details/59486986
  • Spring的IoC容器有两种:BeanFactory 与ApplicationContext.

    • BeanFactory 对 Bean延迟加载,启动时快并占用较少的系统资源
    • ApplicationContext容器启动后,实例化所有singleton,非abstract Bean;当然还可以配置Bean的lazy-init属性,使其延迟加载(注意:如果其他非延迟加载的Bean使用到lazy-init的Bean时,lazy-init的Bean也会立即加载)
  • Spring Bean 生命周期管理

    • Spring IoC容器管理scope=singleton的Bean的生命周期;
    • scope=”prototype”的Bean,容器只负责实例化Bean,但是Bean的销毁则有实例持有者负责.
  • SpringBean 实例化过程

– Main.java
启动IoC容器

package com.pass.information;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.concurrent.CountDownLatch;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("applicationContext-dao.xml");
        context.start();
        System.out.println("-----------------applicationContext finish init---------------------\n");
        System.out.println("启动完成");
        System.out.println("\n-----------------begain to get bean:testProtype---------------------");
        TestProtype prototype = (TestProtype) context.getBean("testProtype");
        System.out.println("\n-----------------begain to get bean:testSingleton---------------------");
        TestSingleton singleton = (TestSingleton) context.getBean("testSingleton");
        Thread.sleep(5000);
        context.destroy();
    }
}


– MyBeanPostProcessor.java
自定义BeanPostProcessor

package com.pass.information;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class MyBeanPostProcessor implements BeanPostProcessor, BeanNameAware, InitializingBean, DisposableBean {
    @Override
    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
        System.out.println(" BeanPostProcessor: postProcessBeforeInitialization.... --->*;" + o.getClass());
        return o;
    }

    @Override
    public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
        System.out.println(" BeanPostProcessor: postProcessAfterInitialization.... ---->*" + o.getClass());
        return o;
    }

    @Override
    public void setBeanName(String s) {
        System.out.println("BeanPostProcessor: BeanNameAware(setBeanName)  ---->*");
    }

    @PostConstruct
    public void annoTestPostConstruct() {
        System.out.println("BeanPostProcessor:annotation postConstruct........ ---->*");
    }

    @PreDestroy
    public void annoTestPostDestroy() {
        System.out.println("BeanPostProcessor:annotation PreDestroy........*");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("BeanPostProcessor: InitializingBean(afterPropertiesSet).... --->*");
    }

    public void initMethod() {
        System.out.println("configure as init-method..... -> *");
    }

    public void destroyMethod() {
        System.out.println("configure as init-destroyMethod..... -> *");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("implments DisposableBean: destroy.... --->*");
    }

}

– TestSingleton.java TestPrototype.java

package com.pass.information;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class TestProtype implements BeanNameAware,InitializingBean,DisposableBean {
    @Override
    public void setBeanName(String s) {
        System.out.println("implements BeanNameAware:setBeanName  ---->P1");
    }

    @PostConstruct
    public void annoTestPostConstruct(){
        System.out.println("annotation postConstruct........ ---->P3");
    }

    @PreDestroy
    public void annoTestPostDestroy(){
        System.out.println("annotation PreDestroy........PD1");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("implments InitializingBean: afterPropertiesSet.... --->P4");
    }

    public void inintMethod(){
        System.out.println("configure as init-method..... -> P5");
    }
    public void destroyMethod(){
        System.out.println("configure as init-destroyMethod..... -> PD3");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("implments DisposableBean: destroy.... --->PD2");
    }


}
package com.pass.information;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * Created by yaoyu.lai on 2017/3/2.
 */

public class TestSingleton implements BeanNameAware, InitializingBean, DisposableBean {
    @Override
    public void setBeanName(String s) {
        System.out.println("implements BeanNameAware:setBeanName  ---->1");
    }

    @PostConstruct
    public void annoTestPostConstruct() {
        System.out.println("annotation postConstruct........ ---->3");
    }

    @PreDestroy
    public void annoTestPostDestroy() {
        System.out.println("annotation PreDestroy........D1");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("implments InitializingBean: afterPropertiesSet.... --->4");
    }

    public void initMethod() {
        System.out.println("configure as init-method..... -> 5");
    }

    public void destroyMethod() {
        System.out.println("configure as destroy-Method..... -> D3");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("implements DisposableBean: destroy.... --->D2");
    }
}

– applicationContext-dao.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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
       xmlns:context="http://www.springframework.org/schema/context"
>
    <context:annotation-config/>
    <bean id="processor" class="com.pass.information.MyBeanPostProcessor" init-method="initMethod" destroy-method="destroyMethod"></bean>
    <bean id="testProtype" class="com.pass.information.TestProtype" scope="prototype" init-method="inintMethod" destroy-method="destroyMethod"></bean>
    <bean id="testSingleton" class="com.pass.information.TestSingleton" init-method="initMethod" destroy-method="destroyMethod" ></bean>


</beans>
  • 执行结果

C:\Java\jdk1.7.0_79\bin\java -Didea.launcher.port=7539 "-Didea.launcher.bin.path=C:\Program Files (x86)\JetBrains\IntelliJ IDEA 2016.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Java\jdk1.7.0_79\jre\lib\charsets.jar;C:\Java\jdk1.7.0_79\jre\lib\deploy.jar;C:\Java\jdk1.7.0_79\jre\lib\ext\access-bridge-64.jar;C:\Java\jdk1.7.0_79\jre\lib\ext\dnsns.jar;C:\Java\jdk1.7.0_79\jre\lib\ext\jaccess.jar;C:\Java\jdk1.7.0_79\jre\lib\ext\localedata.jar;C:\Java\jdk1.7.0_79\jre\lib\ext\sunec.jar;C:\Java\jdk1.7.0_79\jre\lib\ext\sunjce_provider.jar;C:\Java\jdk1.7.0_79\jre\lib\ext\sunmscapi.jar;C:\Java\jdk1.7.0_79\jre\lib\ext\zipfs.jar;C:\Java\jdk1.7.0_79\jre\lib\javaws.jar;C:\Java\jdk1.7.0_79\jre\lib\jce.jar;C:\Java\jdk1.7.0_79\jre\lib\jfr.jar;C:\Java\jdk1.7.0_79\jre\lib\jfxrt.jar;C:\Java\jdk1.7.0_79\jre\lib\jsse.jar;C:\Java\jdk1.7.0_79\jre\lib\management-agent.jar;C:\Java\jdk1.7.0_79\jre\lib\plugin.jar;C:\Java\jdk1.7.0_79\jre\lib\resources.jar;C:\Java\jdk1.7.0_79\jre\lib\rt.jar;C:\workstation\RestFul\SpringMVCRest\target\classes;C:\workstation\code\repository\org\springframework\spring-context\3.2.16.RELEASE\spring-context-3.2.16.RELEASE.jar;C:\workstation\code\repository\org\springframework\spring-aop\3.2.16.RELEASE\spring-aop-3.2.16.RELEASE.jar;C:\workstation\code\repository\aopalliance\aopalliance\1.0\aopalliance-1.0.jar;C:\workstation\code\repository\org\springframework\spring-expression\3.2.16.RELEASE\spring-expression-3.2.16.RELEASE.jar;C:\workstation\code\repository\org\springframework\spring-core\3.2.16.RELEASE\spring-core-3.2.16.RELEASE.jar;C:\workstation\code\repository\commons-logging\commons-logging\1.1.3\commons-logging-1.1.3.jar;C:\workstation\code\repository\org\springframework\spring-beans\3.2.16.RELEASE\spring-beans-3.2.16.RELEASE.jar;C:\workstation\code\repository\org\springframework\spring-webmvc\3.2.16.RELEASE\spring-webmvc-3.2.16.RELEASE.jar;C:\workstation\code\repository\org\springframework\spring-web\3.2.16.RELEASE\spring-web-3.2.16.RELEASE.jar;C:\workstation\code\repository\org\springframework\spring-orm\3.2.16.RELEASE\spring-orm-3.2.16.RELEASE.jar;C:\workstation\code\repository\org\springframework\spring-jdbc\3.2.16.RELEASE\spring-jdbc-3.2.16.RELEASE.jar;C:\workstation\code\repository\org\springframework\spring-tx\3.2.16.RELEASE\spring-tx-3.2.16.RELEASE.jar;C:\workstation\code\repository\com\fasterxml\jackson\core\jackson-databind\2.8.3\jackson-databind-2.8.3.jar;C:\workstation\code\repository\com\fasterxml\jackson\core\jackson-annotations\2.8.0\jackson-annotations-2.8.0.jar;C:\workstation\code\repository\com\fasterxml\jackson\core\jackson-core\2.8.3\jackson-core-2.8.3.jar;C:\workstation\code\repository\com\fasterxml\jackson\dataformat\jackson-dataformat-xml\2.8.3\jackson-dataformat-xml-2.8.3.jar;C:\workstation\code\repository\com\fasterxml\jackson\module\jackson-module-jaxb-annotations\2.8.3\jackson-module-jaxb-annotations-2.8.3.jar;C:\workstation\code\repository\org\codehaus\woodstox\stax2-api\3.1.4\stax2-api-3.1.4.jar;C:\workstation\code\repository\com\fasterxml\woodstox\woodstox-core\5.0.2\woodstox-core-5.0.2.jar;C:\workstation\code\repository\commons-fileupload\commons-fileupload\1.3.1\commons-fileupload-1.3.1.jar;C:\workstation\code\repository\commons-io\commons-io\2.2\commons-io-2.2.jar;C:\Program Files (x86)\JetBrains\IntelliJ IDEA 2016.2.4\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain com.pass.information.informaction_main
三月 03, 2017 2:22:24 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3ea9af11: startup date [Fri Mar 03 14:22:24 CST 2017]; root of context hierarchy
三月 03, 2017 2:22:25 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext-dao.xml]
BeanPostProcessor: BeanNameAware(setBeanName)  ---->*
BeanPostProcessor:annotation postConstruct........ ---->*
BeanPostProcessor: InitializingBean(afterPropertiesSet).... --->*
configure as init-method..... -> *
三月 03, 2017 2:22:26 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@58c1cf91: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,processor,testProtype,testSingleton,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
implements BeanNameAware:setBeanName  ---->1
 BeanPostProcessor: postProcessBeforeInitialization.... --->*;class com.pass.information.TestSingleton
annotation postConstruct........ ---->3
implments InitializingBean: afterPropertiesSet.... --->4
configure as init-method..... -> 5
 BeanPostProcessor: postProcessAfterInitialization.... ---->*class com.pass.information.TestSingleton
-----------------applicationContext finish init---------------------

启动完成

-----------------begain to get bean:testProtype---------------------
implements BeanNameAware:setBeanName  ---->P1
 BeanPostProcessor: postProcessBeforeInitialization.... --->*;class com.pass.information.TestProtype
annotation postConstruct........ ---->P3
implments InitializingBean: afterPropertiesSet.... --->P4
configure as init-method..... -> P5
 BeanPostProcessor: postProcessAfterInitialization.... ---->*class com.pass.information.TestProtype

-----------------begain to get bean:testSingleton---------------------
三月 03, 2017 2:22:31 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@3ea9af11: startup date [Fri Mar 03 14:22:24 CST 2017]; root of context hierarchy
annotation PreDestroy........D1
implements DisposableBean: destroy.... --->D2
configure as destroy-Method..... -> D3
BeanPostProcessor:annotation PreDestroy........*
implments DisposableBean: destroy.... --->*
configure as init-destroyMethod..... -> *
三月 03, 2017 2:22:31 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory destroySingletons

示例总结

– IoC容器优先实例化 实现了BeanPostProcessor接口的Bean ,并且ApplicationContext自动识别BeanPostProcessor,用于扩展对象实例化过程.
– 容器接下来实例化scope=”singleton” Bean

implements BeanNameAware:setBeanName ---->1
BeanPostProcessor: postProcessBeforeInitialization.... --->*;class com.pass.information.TestSingleton
annotation postConstruct........ ---->3
implments InitializingBean: afterPropertiesSet.... --->4
configure as init-method..... -> 5
BeanPostProcessor: postProcessAfterInitialization.... ---->*class com.pass.information.TestSingleton
-----------------applicationContext finish init---------------------

– scope=”prototype”的Bean在第一次调用 getBean()时实例化,实例化过程同上

-----------------begain to get bean:testProtype---------------------
implements BeanNameAware:setBeanName  ---->P1
BeanPostProcessor: postProcessBeforeInitialization.... --->*;class   com.pass.information.TestProtype
annotation postConstruct........ ---->P3
implments InitializingBean: afterPropertiesSet.... --->P4
configure as init-method..... -> P5
BeanPostProcessor: postProcessAfterInitialization.... ---->*class com.pass.information.TestProtype


Bean生命周期文字描述:
1. IoC容器读取xml配置文件
2. 利用java反射或者CGLIB实例化Bean
3. Bean是否实现了Aware相关接口,设置相关依赖
4. 如果容器中有 BeanPostProcessor 实现,则依次调用方法:postProcessBeforeInitialization
5. Bean中有方法 @PostConstruct 注解,则执行该方法.
6. Bean如果实现了 InitializingBean则执行 afterPropertiesSet方法
7. Bean定义中配置了 init-method,则执行该方法
8. 调用BeanPostProcessor,postProcessorAfterInitialization方法.



9. — 容器关闭时,IoC销毁Bean流程—–
10.如果Bean配置了@PreDestroy注解,则执行该方法
11.如果Bean实现了DisposableBean,则调用destroy方法
12.如果Bean配置了destroy-method属性,则执行对应方法

– 容器关闭时,只销毁由容器管理生命周期的bean,对于scope=”prototype”的bean则不处理.

annotation PreDestroy........D1
implements DisposableBean: destroy.... --->D2
configure as destroy-Method..... -> D3
BeanPostProcessor:annotation PreDestroy........*
implments DisposableBean: destroy.... --->*
configure as init-destroyMethod..... -> *

猜你喜欢

转载自blog.csdn.net/littleboyandgirl/article/details/59486986