【 Spring Bean 的生命周期 】

生命周期图

【 Spring Bean 的生命周期 】

生命周期图解释

  1. instantiate:bean 对象实例化
  2. populate properties:封装属性
  3. 如果 Bean 实现 BeanNameAware 执行 setBeanName
  4. 如果 Bean 实现 BeanFactoryAware 执行 setBeanFactory ,获取 Spring 容器
  5. 如果存在类实现 BeanPostProcessor(后处理Bean) ,执行 postProcessBeforeInitialization
  6. 如果 Bean 实现 InitializingBean 执行 afterPropertiesSet
  7. 调用 <bean init-method="init"> 指定初始化方法 init
  8. 如果存在类实现 BeanPostProcessor(处理Bean) ,执行 postProcessAfterInitialization,执行业务处理
  9. 如果 Bean 实现 DisposableBean 执行 destroy
  10. 调用 <bean destroy-method="customerDestroy"> 指定销毁方法 customerDestroy

演示

package cn.ys.model;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;

public class User implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {

    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        System.out.println("2.设置属性"+username);
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public User(){
        System.out.println("1.实例化......");
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    public void setBeanName(String s) {
        System.out.println("3.设置 bean 名字......" + s);
    }

    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        // 把对象放进工厂,即放进容器中
        System.out.println("4.设置 bean 工厂......" + beanFactory);
    }

    public void afterPropertiesSet() throws Exception {
        System.out.println("6.属性赋值完成......");
    }

    public void myInit(){
        System.out.println("7.自定义初始化方法......");
    }

    public void myDestroy(){
        System.out.println("10.自定义销毁方法......");
    }


    public void destroy() throws Exception {
        System.out.println("9.bean 被销毁了......");
    }
}

package cn.ys.spring;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
 * bean 处理器,需要注册给 Spring 容器,统一处理所有的 bean,只需要注册
 */
public class MyBeanPostProcessor implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("5.预处理:" + bean + ":" + beanName);
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("8.后处理:" + bean + ":" + beanName);
        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">

    <bean id="user" class="cn.ys.model.User" init-method="myInit" destroy-method="myDestroy">
        <property name="username" value="张三"></property>
        <property name="password" value="123"></property>
    </bean>

    <!-- 配置 Bean 处理器,Spring 会管理,不用配 id -->
    <bean class="cn.ys.spring.MyBeanPostProcessor"/>

</beans>
package cn.ys.spring;

import cn.ys.model.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class testSpring {

    @Test
    public void testSpringHello() throws Exception {
        // 1、加载 beans.xml 这个 spring 的配置文件,内部就会创建对象
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

        User user = (User) context.getBean("user");

        System.out.println(user);

        // 关闭容器
        context.getClass().getMethod("close").invoke(context);

    }

}

控制台打印

C:\Java\jdk1.8.0_181\bin\java.exe -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.1\lib\idea_rt.jar=54173:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.1\lib\idea_rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.1\plugins\junit\lib\junit-rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.1\plugins\junit\lib\junit5-rt.jar;C:\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Java\jdk1.8.0_181\jre\lib\rt.jar;C:\Users\ys951\Desktop\JavaSETest\JavaEE\Spring\target\test-classes;C:\Users\ys951\Desktop\JavaSETest\JavaEE\Spring\target\classes;C:\Users\ys951\.m2\repository\org\springframework\spring-beans\4.3.19.RELEASE\spring-beans-4.3.19.RELEASE.jar;C:\Users\ys951\.m2\repository\org\springframework\spring-context\4.3.19.RELEASE\spring-context-4.3.19.RELEASE.jar;C:\Users\ys951\.m2\repository\org\springframework\spring-aop\4.3.19.RELEASE\spring-aop-4.3.19.RELEASE.jar;C:\Users\ys951\.m2\repository\org\springframework\spring-core\4.3.19.RELEASE\spring-core-4.3.19.RELEASE.jar;C:\Users\ys951\.m2\repository\org\springframework\spring-expression\4.3.19.RELEASE\spring-expression-4.3.19.RELEASE.jar;C:\Users\ys951\.m2\repository\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;C:\Users\ys951\.m2\repository\junit\junit\4.12\junit-4.12.jar;C:\Users\ys951\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar" com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 -junit4 cn.ys.spring.testSpring,testSpringHello
二月 26, 2019 2:57:49 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@64b8f8f4: startup date [Tue Feb 26 14:57:49 CST 2019]; root of context hierarchy
二月 26, 2019 2:57:49 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans.xml]
1.实例化......
2.设置属性张三
3.设置 bean 名字......user
4.设置 bean 工厂......org.springframework.beans.factory.support.DefaultListableBeanFactory@1e88b3c: defining beans [user,cn.ys.spring.MyBeanPostProcessor#0]; root of factory hierarchy
5.预处理:User{username='张三', password='123'}:user
6.属性赋值完成......
7.自定义初始化方法......
8.后处理:User{username='张三', password='123'}:user
User{username='张三', password='123'}
二月 26, 2019 2:57:50 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@64b8f8f4: startup date [Tue Feb 26 14:57:49 CST 2019]; root of context hierarchy
9.bean 被销毁了......
10.自定义销毁方法......

Process finished with exit code 0