一步步剖析spring bean生命周期

关于spring bean的生命周期,是深入学习spring的基础,也是难点,本篇文章将采用代码+图文结论的方式来阐述spring bean的生命周期,

本篇文章将阐述清楚下图。

一  项目结构及源码

1.程序目录结构

2.applicationContext.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">

    <bean class="com.demo.dao.UserDao" id="userDao" scope="singleton" init-method="myInit" destroy-method="myDestroy">
        <property name="userName" value="Alan_beijing"/>
    </bean>

    <bean class="com.demo.dao.MyBeanPostProcessor" id="myBeanPostProcessor"/>

</beans>

3.UserDao.java

package com.demo.dao;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.apache.log4j.Logger;

public class UserDao implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean,
        DisposableBean{

    private String userName;
    private int count = 0;

    public String getUserName() {
        return userName;
    }

    //2.属性注入,注入属性为userName
    public void setUserName(String userName) {
        count++;
        System.out.println(count + ":注入属性userName="+userName);
        this.userName = userName;
    }

    //1.无参构造函数,实例化时调用该构造函数
    public UserDao() {
        count++;
        System.out.println(count + ":调用构造函数UserDao()");
    }

    //3.实现BeanNameAware,获取bean id
    public void setBeanName(String s) {
        count++;
        System.out.println(count + ":调用setBeanName()获取bean id,bean id=" + s);
    }

    //4.实现BeanFactoryAware,获取bean工厂
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        count++;
        System.out.println(count + ":调用setBeanFactory()获取bean工厂,beanFactory=" + beanFactory);
    }

    //5.实现ApplicationContextAware,获取bean上下文
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        count++;
        System.out.println(count + ":调用setApplicationContext()获取bean上下文,applicationContext=" + applicationContext);
    }

    //6.实现InitializingBean,获取afterPropertiesSet
    public void afterPropertiesSet() throws Exception {
        count++;
        System.out.println(count + ":调用afterPropertiesSet()");
    }

    //7.自定义初始化方法myInit()
    public void myInit() {
        count++;
        System.out.println(count + ":调用自定义myInit()");
    }

    //8.实现DisposableBean,获取destroy()
    public void destroy() throws Exception {
        count++;
        System.out.println(count + ":destroy()");
    }

    //9.自定义销毁方法myDestroy()
    public void myDestroy() {
        count++;
        System.out.println(count + ":调用自定义destroy()");
    }
}
4.MyBeanPostProcessor.java
package com.demo.dao;

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

public  class MyBeanPostProcessor implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("=====调用postProcessBeforeInitialization()=====");
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("=====调用postProcessAfterInitialization()=====");
        return bean;
    }
}

 二  测试代码及测试结果

1.test.java

package com.demo.test;

import com.demo.dao.UserDao;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {

    @Test
    public void test() {
        //定义容器并初始化
        //ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        applicationContext.getBean(UserDao.class);
        //只有关闭容器时,才会调用destroy方法
        applicationContext.registerShutdownHook();
    }
}

2.测试结果

三 分析

通过如上测试结果,bean生命周期流程大致如下:

1.装配bean

bean装配为bean生命周期第一环节。所谓装配bean,指将java对象转换为bean的过程。在该示例中,UserDao.jave和MyBeanPostProcessor通过xml方式转化为bean。

注意:spring框架支持四种方式装配bean:xml方式,java代码方式,自动装配和混合装配方式

2.加载applicationContext.xml并实例化

加载并实例化bean为bean生命周期的第二环节。本文示例通过ClassPathXmlApplicationContext()来加载并,当bean为singleton时,该过程就实例化对象,而不需要等待

调用applicationContext.getBean()获取bean时才实例化对象,这与prototype是不一样的。

3.属性注入

bean属性注入为bean生命周期第三环节,采用反射方式注入bean.

4.实现BeanNameAware,获取bean id

该过程为bean生命周期的第四环节,实现该接口,可以获取bean的id

5.实现BeanFactoryAware,获取bean 工厂

该过程为bean生命周期第五环节,通过实现BeanFactoryAware获取bean工厂

6.实现ApplicationContextAware,获取运用上下文

该过程为bean生命周期第六环节,通过实现ApplicationContextAware接口,获取bean上下文

7.调用Bean后置处理器,before

该过程为bean生命周期第七环节,通过实现后置处理器BeanPostProcessor获取before和after,该过程是通过AOP方式实现的,在before和after之间,发生如下8,9过程。

8.实现InitializingBean的afterPropertiesSet(),获取初始化方法

该过程为bean生命周期第八环节,通过实现InitializingBean,获取afterPropertiesSet()

9.调用自定义初始化方法,init-method

该过程为bean生命周期第九环节,实现自定义初始化方法

10.调用Bean后置处理器after

该过程为bean生命周期第十环节,后置处理器最后环节

11.关闭容器AbstractApplicationContext.registerShutDownHook()

该环节为bean生命周期第十一环节,关闭容器

12.调用DisposableBean的destroy()

该过程为bean生命周期第十二环节,实现DisposableBean接口,调用destroy()

13.调用定制化销毁方法destroy-method

该过程为bean生命周期最后环节,调用自定义销毁方法destroy-method

 三  版权区

  • 转载博客,必须注明博客出处
  • 博主网址:http://www.cnblogs.com/wangjiming/
  • 如您有新想法,欢迎提出,邮箱:[email protected]
  • 专业.NET之家技术QQ群:490539956
  • 专业化Java之家QQ群:924412846
  • 有问必答QQ群:2098469527
  • 一对一技术辅导QQ:2098469527

原文地址:https://www.cnblogs.com/wangjiming/p/11669091.html

时间: 2024-11-10 20:40:53

一步步剖析spring bean生命周期的相关文章

Spring点滴四:Spring Bean生命周期

Spring Bean 生命周期示意图: 了解Spring的生命周期非常重要,我们可以利用Spring机制来定制Bean的实例化过程. --------------------------------------------------------------------------------------------------------------------------------------------------- spring-service.xml: <?xml version=

Spring Bean生命周期

1.Bean的建立:BeanFactory容器寻找Bean的定义信息,读取Bean定义文件,并将其实例化,生成各个Bean实例.2.属性注入:使用依赖注入,Spring按照Bean定义信息配置Bean所有属性.3.BeanNameAware的setBeanName():传递Bean的ID.4.BeanFactoryAware的setBeanFactory():工厂调用setBeanFactory()方法传入工厂自身.如果是使用ApplicationContext来生成并管理Bean的话则稍有不同

Spring Bean 生命周期

转自:也谈Spring Bean的生命周期 开篇先用一张老图描述下Spring中Bean容器的生命周期. 插叙一下,记得某个博文中提到:“Spring的Bean容器只管理非单例Bean的生命周期,单例Bean的生命周期不在管理范围内”,其实我认为这句话恰好说反了.首先明确一点,并非Spring容器中所有的Bean都有生命周期行为,只有接受容器管理生命周期的Bean才具有生命周期行为:而单例(Singleton)Bean接受容器管理,非单例(non-singleton)Bean在实例化后,完全交给

Spring Bean生命周期详解

对象生命周期:创建(实例化----初始化)---使用----销毁,而在Spring中,Bean对象周期当然遵从这一过程,但是Spring提供了许多对外接口,允许开发者对三个过程(实例化.初始化.销毁)的前后做一些操作.在Spring Bean中,实例化是为Bean对象开辟空间(构造函数),初始化则是对属性的初始化,属性注入(setter方法注入属性). 1.Bean自身方法:init-method/destroy-method,通过为配置文件bean定义中添加相应属性指定相应执行方法. 2.Be

11张流程图帮你搞定 Spring Bean 生命周期

在网上已经有跟多Bean的生命周期的博客,但是很多都是基于比较老的版本了,最近吧整个流程化成了一个流程图.待会儿使用流程图,说明以及代码的形式来说明整个声明周期的流程.注意因为代码比较多,这里的流程图只画出了大概的流程,具体的可以深入代码 一.获取Bea 第一阶段获取Bean 这里的流程图的入口在 AbstractBeanFactory类的 doGetBean方法,这里可以配合前面的 getBean方法分析文章进行阅读.主要流程就是 1.先处理Bean 的名称,因为如果以“&”开头的Bean名称

Spring Bean生命周期回调方法

参阅官方文档:https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-lifecycle 第一种方式:使用@PostConstruct注解,进行标注当前非init()名称的方法,进行bean声明周期的初始化操作:@PostConstruct和@PreDestroy是当前Bean声明周期的初始化回调和销毁时回调 第二种方式:当前类实现InitializingBean和

Spring Bean生命周期回调

参阅官方文档:https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-lifecycle 第一种方式:使用@PostConstruct注解,进行标注当前非init()名称的方法,进行bean声明周期的初始化操作:@PostConstruct和@PreDestroy是当前Bean声明周期的初始化回调和销毁时回调 第二种方式:当前类实现InitializingBean和

spring bean生命周期和上下文初始化

第一阶段: 1 准备阶段根据BeanDefintionReader去初始化Bean的定义,那么在bean的定义中通常有两种一个是注解Bean定义读取器,一个是xmlBean定义读取器. BeanDefinition是spring中Bean的元数据定义: 包括:(1)bean的Scope:(2)是否懒加载:(3)simpleName:(4)parentName,(5)DependsOn 在doCreateBean中的4个方法 1 createBeanInstance2 populateBean3

spring bean 生命周期事件

整体流程图 程序示例 maven依赖 <dependencies> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <vers