ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring之bean的生命周期

2022-08-11 17:30:35  阅读:83  来源: 互联网

标签:生命周期 -- Spring Bean System bean println public out


Spring之bean的生命周期

在传统的Java应用中,bean的生命周期很简单,使用Java关键字 new 进行Bean 的实例化,然后该Bean 就能够使用了。一旦bean不再被使用,则由Java自动进行垃圾回收。

相比之下,Spring管理Bean的生命周期就复杂多了,正确理解Bean 的生命周期非常重要,因为Spring对Bean的管理可扩展性非常强,下面展示了一个Bean的构造过程

image

  1. Bean 容器找到配置文件中 Spring Bean 的定义。
  2. Bean 容器利用 Java Reflection API 创建一个 Bean 的实例。
  3. 如果涉及到一些属性值 利用 set()方法设置一些属性值。
  4. 如果实现了其他 *.Aware接口,就调用相应的方法。
  5. 如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行postProcessBeforeInitialization() 方法
  6. 如果 Bean 实现了InitializingBean接口,执行afterPropertiesSet()方法。
  7. 如果 Bean 在配置文件中的定义包含 init-method 属性,执行指定的方法。
  8. 如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行postProcessAfterInitialization() 方法
  9. 当要销毁 Bean 的时候,如果 Bean 实现了 DisposableBean 接口,执行 destroy() 方法。
  10. 当要销毁 Bean 的时候,如果 Bean 在配置文件中的定义包含 destroy-method 属性,执行指定的方法。

BeanFactory 的注释里,有这么一段话,如下图所示:
image

代码演示

  1. 新建一个 User 类,让其实现接口 BeanNameAwareBeanFactoryAwareInitializingBeanDiposableBean 这4个接口,以及编写userInit()userDestroy() 两个方法,对应配置文件中 <bean>init-methoddestroy-method
package com.wqing.domain;

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

/**
 * @Description 用于演示 Bean 的生命周期
 * @Author wqing
 * @Date 2022/8/11 15:37
 */
public class User implements BeanNameAware, BeanFactoryAware,
        InitializingBean, DisposableBean {
    private String name;
    private Integer age;

    private BeanFactory beanFactory;
    private String beanName;

    public User() {
        System.out.println("[构造器]--调用Person的构造函数进行实例化");
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        System.out.println("[属性填充]--注入属性age");
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    //这是 BeanFactoryAware 接口的方法
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("[BeanFactoryAware]--执行BeanFactoryAware.setBeanFactory(),beanFactory为:" + beanFactory);
        this.beanFactory = beanFactory;
    }

    //这是 BeanNameAware 接口的方法
    @Override
    public void setBeanName(String name) {
        System.out.println("[BeanNameAware]--执行BeanNameAware.setBeanName(),beanName为: " + name);
        this.beanName = name;
    }

    //这是 DisposableBean 接口的方法
    @Override
    public void destroy() throws Exception {
        System.out.println("[DisposableBean]--执行DisposableBean.destroy()");
    }

    //这是 InitializingBean 接口的方法
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("[InitializingBean]--执行InitializingBean.afterPropertiesSet()");
    }

    // 通过<bean>的init-method属性指定的初始化方法
    public void userInit() {
        System.out.println("[init-method]--执行<bean>的init-method属性指定的初始化方法");
    }

    // 通过<bean>的destroy-method属性指定的初始化方法
    public void userDestroy() {
        System.out.println("[destroy-method]--执行<bean>的destroy-method属性指定的销毁方法");
    }
}

  1. 自定义 MyBeanPostProcessor 实现 BeanPostProcessor
package com.wqing.domain;

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

/**
 * @Description
 * @Author 王清
 * @Date 2022/8/11 16:06
 */
public class MyBeanPostProcessor implements BeanPostProcessor {
    /**
     * 实例化、依赖注入完毕,在调用显示的初始化之前完成一些定制的初始化任务
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("[BeanPostProcessor]--执行BeanPostProcessor.postProcessBeforeInitialization()");
        return bean;
    }

    /**
     * 实例化、依赖注入、初始化完毕时执行
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("[BeanPostProcessor]--执行BeanPostProcessor.postProcessAfterInitialization()");
        return bean;
    }
}

BeanPostProcessor 接口包括2个方法 postProcessAfterInitializationpostProcessBeforeInitialization,这两个方法的第一个参数都是要处理的Bean对象,第二个参数都是Bean的name。返回值也都是要处理的Bean对象。

  1. 编写 application.xml,将 UserMyBeanPostProcessor 注册进容器
<?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="com.wqing.domain.User" init-method="userInit"
          destroy-method="userDestroy">
        <property name="name" value="张三"/>
        <property name="age" value="20"/>
    </bean>

    <bean id="myBeanPostProcessor" class="com.wqing.domain.MyBeanPostProcessor"/>
</beans>
  1. 编写测试类
package com.wqing;

import com.wqing.domain.User;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Description
 * @Author wqing
 * @Date 2022/8/5 14:38
 */
public class Test {
    public static void main(String[] args) {
        System.out.println("容器开始创建");
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        User bean = context.getBean(User.class);
        System.out.println("使用 bean");
        System.out.println(bean);
        System.out.println("容器开始销毁");
        context.close();
    }
}

执行结果

容器开始创建
[构造器]--调用Person的构造函数进行实例化
[属性填充]--注入属性name
[属性填充]--注入属性age
[BeanNameAware]--执行BeanNameAware.setBeanName(),beanName为: user
[BeanFactoryAware]--执行BeanFactoryAware.setBeanFactory(),beanFactory为:org.springframework.beans.factory.support.DefaultListableBeanFactory@38082d64: defining beans [user,myBeanPostProcessor]; root of factory hierarchy
[BeanPostProcessor]--执行BeanPostProcessor.postProcessBeforeInitialization()
[InitializingBean]--执行InitializingBean.afterPropertiesSet()
[init-method]--执行<bean>的init-method属性指定的初始化方法
[BeanPostProcessor]--执行BeanPostProcessor.postProcessAfterInitialization()
使用 bean
Person{name='张三', age=20}
容器开始销毁
[DisposableBean]--执行DisposableBean.destroy()
[destroy-method]--执行<bean>的destroy-method属性指定的销毁方法

标签:生命周期,--,Spring,Bean,System,bean,println,public,out
来源: https://www.cnblogs.com/wqstart/p/16576851.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有