浅谈Spring bean 生命周期验证

一、从源码注释看bean生命周期

从JDK源码上看,BeanFactory实现类需要支持Bean的完整生命周期,完整的初始化方法及其标准顺序(格式:接口 方法)为:

1.BeanNameAware setBeanName 设置bean名称
2.BeanClassLoaderAware setBeanClassLoader 设置bean类加载器
3.BeanFactoryAware setBeanFactory 设置bean工厂
4.EnvironmentAware setEnvironment 设置环境:profiles+properties
5.EmbeddedValueResolverAware setEmbeddedValueResolver 设置嵌入式值解析器
6.ResourceLoaderAware setResourceLoader 设置资源载入器,只适用于在应用程序上下文中运行
7.ApplicationEventPublisherAware setApplicationEventPublisher注入应用事件发布器ApplicationEventPublisher
8.MessageSourceAware setMessageSource 设置国际化支持
9.ApplicationContextAware setApplicationContext 设置应用上下文
10.ServletContextAware setServletContext 设置servlet上下文
11.BeanPostProcessors postProcessBeforeInitialization 执行bean处理器前置方法
12.InitializingBean afterPropertiesSet 执行初始化Bean设置完属性后置方法
13.a custom init-method definition 执行自定义初始化方法
14.BeanPostProcessors postProcessAfterInitialization 执行bean处理器后置方法

销毁顺序:

1.DestructionAwareBeanPostProcessors postProcessBeforeDestruction 销毁处理器的前置方法
2.DisposableBean destroy Bean销毁回调方法
3.a custom destroy-method definition 用户自定义销毁方法

核心方法流程图:

二、测试验证

2.1分析原理

前面说的17个步骤都可以测试,我们选取其中的8个步骤进行测试如下:

初始化流程:

1.BeanNameAware setBeanName 设置bean名称
3.BeanFactoryAware setBeanFactory 设置bean工厂
11.BeanPostProcessors postProcessBeforeInitialization 执行bean处理器前置方法
12.InitializingBean afterPropertiesSet 执行初始化Bean设置完属性后置方法
13.a custom init-method definition 执行自定义初始化方法
14.BeanPostProcessors postProcessAfterInitialization 执行bean处理器后置方法

销毁流程:

2.DisposableBean destroy Bean销毁回调方法
3.a custom destroy-method definition 用户自定义销毁方法

 2.2 代码清单

1.构建一个Person类,实现BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean接口。

package spring.ioc;

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 Person implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean {

  private String name;

  private String mobile;

  public Person() {
    super();
    System.out.println("[构造器] 调用Person的构造器实例化");
  }

  public String getName() {
    return name;
  }

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

  public String getMobile() {
    return mobile;
  }

  public void setMobile(String mobile) {
    System.out.println("[属性注入] mobile="+mobile);
    this.mobile = mobile;
  }

  @Override
  public void destroy() throws Exception {
    System.out.println("[接口DisposableBean.destroy() ]");
  }

  @Override
  public void afterPropertiesSet() throws Exception {
    System.out.println("[接口InitializingBean.afterPropertiesSet() ]");
  }

  @Override
  public void setBeanName(String name) {
    System.out.println("[接口BeanNameAware.setBeanName() ]");
  }

  @Override
  public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    System.out.println("[接口BeanFactoryAware.setBeanFactory() ]");
  }

  public void myInit(){
    System.out.println("[init-method]调用<bean>的init-method属性指定的初始化方法");
  }

  public void myDestory() {
    System.out.println("[destroy-method]调用<bean>的destroy-method属性指定的销毁方法");
  }

}

2.自定义工厂后处理器,复写postProcessBeanFactory方法,获取bean定义后添加属性mobile=110

package spring.ioc;

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

/**
 *
 * @ClassName:MyBeanFactoryPostProcessor
 * @Description:自定义工厂后处理器
 * @author diandian.zhang
 * @date 2017年10月25日下午7:14:09
 */
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

  public MyBeanFactoryPostProcessor() {
    super();
    System.out.println("[MyBeanFactoryPostProcessor工厂后处理器]BeanFactoryPostProcessor实现类构造器!!");
  }

  @Override
  public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0)
      throws BeansException {
    System.out.println("[MyBeanFactoryPostProcessor工厂后处理器]BeanFactoryPostProcessor.postProcessBeanFactory()获取bean定义后添加属性mobile=110");
    BeanDefinition bd = arg0.getBeanDefinition("person");
    bd.getPropertyValues().addPropertyValue("mobile", "110");
  }

}

3.自定义Bean后处理器,复写postProcessBeforeInitialization和postProcessAfterInitialization2个方法,分别对应初始化前后时的操作。

package spring.ioc;

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

/**
 *
 * @ClassName:MyBeanPostProcessor
 * @Description:自定义Bean后处理器
 * @author diandian.zhang
 * @date 2017年10月25日下午7:03:53
 */
public class MyBeanPostProcessor implements BeanPostProcessor {

  public MyBeanPostProcessor() {
    super();
    System.out.println("这是BeanPostProcessor实现类构造器!!");
  }

  /**
   *
   * @Description 初始化前,处理器
   * @param bean
   * @param beanName
   * @return
   * @throws BeansException
   * @author diandian.zhang
   * @date 2017年10月25日下午7:07:02
   * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
   */
  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    System.out.println("BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!beanName="+beanName);
    return bean;
  }

  /**
   *
   * @Description 初始化后,处理器
   * @param bean
   * @param beanName
   * @return
   * @throws BeansException
   * @author diandian.zhang
   * @date 2017年10月25日下午7:07:07
   * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
   */
  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    System.out.println("BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!beanName="+beanName);
    return bean;//注意,如果返回null,后续BeanPostProcessor不会再执行
  }

}

4.自定义实例化bean后处理器适配器,复写postProcessBeforeInstantiation、postProcessBeforeInstantiation、postProcessPropertyValues分别对应实例化Bean前调用、实例化Bean后调用、设置某个属性时调用

注意:InstantiationAwareBeanPostProcessorAdapter ,这里是实例化Instantiation,不是初始化Initialization!!!

package spring.ioc;

import java.beans.PropertyDescriptor;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;

/**
 *
 * @ClassName:MyInstantiationAwareBeanPostProcessor
 * @Description:BeanPostProcessor的子类,增加了更多自定方法
 * @author diandian.zhang
 * @date 2017年10月25日下午7:09:15
 */
public class MyInstantiationAwareBeanPostProcessor extends
    InstantiationAwareBeanPostProcessorAdapter {

  public MyInstantiationAwareBeanPostProcessor() {
    super();
    System.out.println("这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!");
  }

  // 接口方法、实例化Bean之前调用
  @Override
  public Object postProcessBeforeInstantiation(Class<?> beanClass,String beanName) throws BeansException {
    System.out.println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法[实例化Bean之前调用 ]beanname="+beanName);
    return null;
  }

  // 接口方法、实例化Bean之后调用
  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName)
      throws BeansException {
    System.out .println("InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法[实例化Bean之后调用]beanname="+beanName);
    return bean;
  }

  // 接口方法、设置某个属性时调用
  @Override
  public PropertyValues postProcessPropertyValues(PropertyValues pvs,
      PropertyDescriptor[] pds, Object bean, String beanName)
      throws BeansException {
    System.out.println("InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法 pvs="+pvs+",beanName="+beanName);
    return pvs;
  }
}

5.测试类,使用ClassPathXmlApplicationContext从xml中读取bean配置文件生成applicationContext容器应用上下文,这一步对应容器初始化。第二部从应用上下文中获取bean。最后一步注册一个关闭钩子,在容器关闭时触发。

package spring.ioc;

import org.junit.Test; 6 import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;10
import spring.aop.xml.dao.Dao;

/**
 *
 * @ClassName:IOCTest
 * @Description:测试类
 * @author diandian.zhang
 * @date 2017年10月25日下午4:42:01
 */
public class IOCTest {

  @Test
  public void iocPersonTest(){
    System.out.println("=============容器初始化======start=========");
    @SuppressWarnings("resource")
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("simple_spring_bean.xml");//源码入口
    System.out.println("=============容器初始化=======end========");
    System.out.println("=============获取person bean====start=======");
    Person person = applicationContext.getBean("person",Person.class);//获取Bean
    System.out.println("=============获取person bean====end=======,person类名="+person.getClass().getName());
    System.out.println("=============注册关闭钩子,关闭容器(JVM shutdown)时触发钩子!================");
    ((ClassPathXmlApplicationContext)applicationContext).registerShutdownHook();
  }
}

直接运行,结果如下:

=============容器初始化======start=========
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
[MyBeanFactoryPostProcessor工厂后处理器]BeanFactoryPostProcessor实现类构造器!!
[MyBeanFactoryPostProcessor工厂后处理器]BeanFactoryPostProcessor.postProcessBeanFactory()获取bean定义后添加属性mobile=110
这是BeanPostProcessor实现类构造器!!
这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!
InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法[实例化Bean之前调用 ]beanname=person
[构造器] 调用Person的构造器实例化
InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法 pvs=PropertyValues: length=2; bean property 'mobile'; bean property 'name',beanName=person
[属性注入] mobile=110
[属性注入] name=张三
[接口BeanNameAware.setBeanName() ]
[接口BeanFactoryAware.setBeanFactory() ]
BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!beanName=person
[接口InitializingBean.afterPropertiesSet() ]
[init-method]调用<bean>的init-method属性指定的初始化方法
BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!beanName=person
InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法[实例化Bean之后调用]beanname=person
=============容器初始化=======end========
=============获取person bean====start=======
=============获取person bean====end=======,person类名=spring.ioc.Person
=============注册关闭钩子,关闭容器(JVM shutdown)时触发钩子!================
[接口DisposableBean.destroy() ]
[destroy-method]调用<bean>的destroy-method属性指定的销毁方法

总结流程:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解Spring中Bean的生命周期和作用域及实现方式

    前言 在applicationContext.xml中配置完bean之后,Bean的声明周期状态有哪些.生命周期的各个阶段可以做什么.在applicationContext.xml配置bean的作用域有哪些.其中各个作用域代表的是什么.适用于什么情况.这篇文章做一个记录. 生命周期 初始化 可以直接查看图片,图片来自Spring Bean Life Cycle 从上图看出,Bean初始化完成包括9个步骤.其中一些步骤包括接口的实现,其中包括BeanNameAware接口,BeanFactoryA

  • spring之Bean的生命周期详解

    Bean的生命周期: Bean的定义--Bean的初始化--Bean的使用--Bean的销毁 Bean的定义 Bean 是 spring 装配的组件模型,一切实体类都可以配置成一个 Bean ,进而就可以在任何其他的 Bean 中使用,一个 Bean 也可以不是指定的实体类,这就是抽象 Bean . Bean的初始化 Spring中bean的初始化回调有两种方法 一种是在配置文件中声明init-method="init",然后在一个实体类中用init()方法来初始化 另一种是实现Ini

  • 深入理解Spring中bean的生命周期介绍

    1.以ApplocationContext上下文单例模式装配bean为例,深入探讨bean的生命周期: (1).生命周期图: (2).具体事例: person类实现BeanNameAware,BeanFactoryAware接口 public class Person implements BeanNameAware ,BeanFactoryAware{ private String name; public Person(){ System.out.println("调用构造器为属性值初始化&

  • Spring Bean的生命周期详细介绍

    Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的.我们通常使用ApplicationContext作为Spring容器.这里,我们讲的也是 ApplicationContext中Bean的生命周期.而实际上BeanFactory也是差不多的,只不过处理器需要手动注册. 一.生命周期流程图: Spring Bean的完整生命周期从创建Spring容器开始,直到最终Spring容器销毁Bean,这其中包含了一系列关

  • 详解Java的Spring框架中bean的定义以及生命周期

    bean的定义 形成应用程序的骨干是由Spring IoC容器所管理的对象称为bean.bean被实例化,组装,并通过Spring IoC容器所管理的对象.这些bean由容器提供,例如,在XML的<bean/>定义,已经看到了前几章的形式配置元数据创建. bean定义包含所需要的容器要知道以下称为配置元数据的信息: 如何创建一个bean Bean 生命周期的详细信息 Bean 依赖关系 上述所有配置元数据转换成一组的下列属性构成每个bean的定义. Spring配置元数据 Spring IoC

  • Spring配置使用之Bean生命周期详解

    基本概念 Spring 中的 Bean 的生命周期,指的是 Bean 从创建到销毁的过程. 下面来探究下几个有关 Bean 生命周期配置的属性. lazy-init lazy-init 表示延迟加载 Bean,默认在 Spring IoC 容器初始化时会实例化所有在配置文件定义的 Bean,若启用了 lazy-init 则在调用 Bean 时才会去创建 Bean. 定义 Bean: public class Animals { public Animals(){ System.out.print

  • 详解Spring中bean生命周期回调方法

    生命周期回调方法 对于spring bean来讲,我们默认可以指定两个生命周期回调方法.一个是在ApplicationContext将bean初始化,包括注入对应的依赖后的回调方法:另一个是在ApplicationContext准备销毁之前的回调方法.要实现这种回调主要有三种方式:实现特定的接口.在XML配置文件中指定回调方法和使用JSR-250标准的注解. 1 实现特定接口 针对bean初始化后的回调和ApplicationContext销毁前的回调,Spring分别为我们了提供了Initia

  • 浅谈Spring bean 生命周期验证

    一.从源码注释看bean生命周期 从JDK源码上看,BeanFactory实现类需要支持Bean的完整生命周期,完整的初始化方法及其标准顺序(格式:接口 方法)为: 1.BeanNameAware setBeanName 设置bean名称 2.BeanClassLoaderAware setBeanClassLoader 设置bean类加载器 3.BeanFactoryAware setBeanFactory 设置bean工厂 4.EnvironmentAware setEnvironment

  • 谈谈我对Spring Bean 生命周期的理解

    前言 Spring的ioc容器功能非常强大,负责Spring的Bean的创建和管理等功能.而Spring 的bean是整个Spring应用中很重要的一部分,了解Spring Bean的生命周期对我们了解整个spring框架会有很大的帮助. BeanFactory和ApplicationContext是Spring两种很重要的容器,前者提供了最基本的依赖注入的支持,而后者在继承前者的基础进行了功能的拓展,例如增加了事件传播,资源访问和国际化的消息访问等功能.本文主要介绍了ApplicationCo

  • 浅谈Cookie的生命周期问题

    设置Cookie对象的有效时间, setMaxAge()方法便可以设置Cookie对象的有效时间, 例如:Cookie c = new Cookie("username","john"); c.setMaxAge(60);//60秒的意思 c.setMaxAge(60*60);//一小时 c.setMaxAge(365*24*60*60);//一年 如果不设置过期时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了. 这种生

  • 浅谈Spring Bean的基本配置

    一.Spring中set方法的注入 User实体 @Data //lombok提供的有参构造 @AllArgsConstructor lombok提供的无参构造 @NoArgsConstructor public class User { private int id; private String name; private int age; private String sex; private String birthday; } beanFactory.xml <bean id="

  • 浅谈Unity脚本生命周期与执行顺序

    一.脚本生命周期 Unity脚本中的常见必然事件如下表所示 名称 触发时机 用途 Awake 脚本实例被创建时调用 用于游戏对象的初始化,注意Awake的执行早于所有脚本的Start函数 OnEnable 当对象变为可用或激活状态时被调用 用途 Start Update函数第一次运行之前调用 用于游戏对象的初始化 Update 每帧调用一次 用于更新游戏场景和状态 FixedUpdate 每个固定物理时间间隔调用一次 用于物理状态的更新 LateUpdate 每帧调用一次(在update之后调用

  • Spring Bean生命周期详细分析

    目录 前言 一.Bean的介绍 什么是Bean Bean的生命周期 Bean的作用域 二.详细过程 1. Bean的实例化 2. InstantiationAwareBeanPostProcessor 3. 设置属性(依赖注入) 4. 注入Aware接口 5. BeanPostProcessor的postProcessBeforeInitialzation方法 6. InitializingBean与init-method 7. BeanPostProcess的postProcessAfterI

  • 全面详解Spring Bean生命周期教程示例

    目录 Spring 中 Bean 的生命周期 Bean 的实例化 构造方法注入 工厂方法注入 Bean 的属性赋值 setter注入 构造方法注入 Bean 的初始化 初始化方法 InitializingBean 接口 Bean 的销毁 销毁方法 DisposableBean 接口 总结 Spring 中 Bean 的生命周期 是当今最流行的 Java 开发框架之一,其强大的 Bean容器机制是其中的核心之一.Bean 是指在 Spring 容器中被管理的对象,它们可以被注入到其他对象中,也可以

  • Spring Bean生命周期源码原理图解

    概述 spring流行了很长时间了,是一个用java编写的轻量级框架,受到了很多公司及程序员的欢迎,Bean生命周期是一个对象从实例化开始到销毁的全过程,了解生命周期是很有必要的. 重要性 spring的生命周期是比较复杂的,只有了解其过程及原理才能更好的扩展程序. 源码剖析生命周期过程bean的实例化 属性填充及Aware接口检测设置依赖 如果容器自定义了BeanpostProcessor的实现类,则执行处理器相应的前置处理 bean实现了初始化接口InitlializingBean,则会执行

  • 浅谈VUE uni-app 生命周期

    目录 一.应用的生命周期 二.页面生命周期 三.组件生命周期 总结 一.应用的生命周期 onLaunch 当uni-app 初始化完成时触发(全局只触发一次)onShow 当 uni-app 启动,或从后台进入前台显示onHide 当 uni-app 从前台进入后台 二.页面生命周期 onLoad 监听页面加载onReady 监听页面初次渲染完成.注意如果渲染速度快,会在页面进入动画完成前触发onShow 监听页面显示.页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面onHide 监

  • 浅谈vue的生命周期

    目录 1.什么是生命周期?有什么作用? 2.第一次加载页面会触发哪几个钩子? 3.简述每个周期应用于哪个场景? 4.created和mounted的区别 5.vue在哪个生命周期获取数据? 总结 1.什么是生命周期?有什么作用? 每一个vue实例在创建时都要经历一系列的初始化过程-----例如需要设置监听,编译模板,将实例挂载到dom并在数据发生变化时更新dom等等.同时这个时候也会运行一些生命周期钩子的函数,这些函数,给用户在不同阶段添加代码的机会.例如:如果需要某些插件操作dom节点,如果想

随机推荐