SpringBean生命周期详解-程序员宅基地

技术标签: 声明周期  SpringBean生命周期  SpringBean  Spring  Bean  

SpringBean生命周期详解

一、简述:

Spring是我们每天都在使用的框架,Bean是被Spring管理的Java对象,是Spring框架最重要的部分之一,那么让我们一起了解一下Spring中Bean的生命周期是怎样的吧

二、流程图

在这里插入图片描述

总体分为四个阶段:

  ①实例化 CreateBeanInstance
  ②属性赋值 PopulateBean
  ③初始化 Initialization
  ④销毁 Destruction**

其中多个增强接口贯穿了这四个阶段!

三、SpringBean生命周期中的增强接口PostProcessor:

在上图里有多种后置处理器接口,它们贯穿了Bean的生命周期,且它们的实现类都会在SpringIOC容器进行初始化的时候进行实例化,让我们来做一个区分:

|  |  ||--|--||  |  |

解释:

Bean的实例化:
是指Spring通过反射获取Bean的构造方法进行实例化的过程
Bean的初始化:
是指Bean的属性赋值、执行初始化方法(init-method)的过程

四、实例展示

SpringBeanDemo

package com.rx.spring;
 
import com.rx.spring.domain.Person;
import com.rx.spring.domain.Student;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 
public class SpringBeanDemo {
    
    public static void main(String[] args) throws Exception {
    
        System.out.println("****开始启动****");
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);
        System.out.println("****启动完毕****");
        Person person = applicationContext.getBean("person", Person.class);
        Student student = applicationContext.getBean("student", Student.class);
 
        System.out.println("=============================================");
        System.out.println("person:" + person);
        System.out.println("student:" + student);
        person.destroy();
 
        System.out.println("============现在开始关闭容器======================");
        applicationContext.registerShutdownHook();
    }
}

Config

package com.rx.spring;
 
import org.springframework.context.annotation.*;
 
@Configuration
@ComponentScan("com.rx.spring")
@ImportResource("classpath:spring.xml")
public class Config {
    
     
}

Person

package com.rx.spring.domain;
 
import lombok.Data;
import org.springframework.beans.factory.DisposableBean;
 
@Data
public class Person implements DisposableBean {
    
    private String name;
    private String address;
    private String tel;
 
    public Person(String name, String address, String tel) {
    
        System.out.println("Person--->>>有参构造方法");
        this.name = name;
        this.address = address;
        this.tel = tel;
    }
 
    public Person() {
    
        System.out.println("Person--->>>无参构造方法");
    }
 
    private void raoInitMethod() {
    
        System.out.println("person--->>>InitMethod...");
    }
 
    private void raoDestroyMethod() {
    
        System.out.println("person--->>>DestroyMethod...");
    }
 
    @Override
    public void destroy() throws Exception {
    
        System.out.println("【DisposableBean接口】调用DisposableBean.destroy()");
    }
}

Student

package com.rx.spring.domain;
 
import lombok.Data;
import org.springframework.beans.factory.DisposableBean;
 
@Data
public class Student implements DisposableBean {
    
    private String username;
    private String password;
 
    public Student(String username, String password) {
    
        System.out.println("student--->>有参构造方法");
        this.username = username;
        this.password = password;
    }
    public Student() {
    
        System.out.println("student--->>>无参构造方法");
    }
 
    private void raoInitMethod() {
    
        System.out.println("student--->>>InitMethod...");
    }
 
    private void raoDestroyMethod() {
    
        System.out.println("student--->>>DestroyMethod...");
    }
 
    @Override
    public void destroy() throws Exception {
    
        System.out.println("【DisposableBean接口】调用DisposableBean.destroy()");
    }
}

RaoBeanFactoryPostProcessor

package com.rx.spring.beanfactorypostprocessor;
 
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
 
@Component
public class RaoBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
        System.out.println("postProcessBeanFactory...");
        String[] beanStr = beanFactory.getBeanDefinitionNames();
        for (String beanName : beanStr) {
    
            if ("person".equals(beanName)) {
    
                BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
                MutablePropertyValues m = beanDefinition.getPropertyValues();
                if (m.contains("address")) {
    
                    //这个方法是判断是否有propertyName=username,有就替换,没有就添加
                    m.addPropertyValue("address", "大兴区");
                    System.out.println("***修改了address属性初始值了***");
                }
            }
        }
    }
}

RaoInstantiationAwareBeanPostProcessor

package com.rx.spring.beanpostprocessor;
 
import com.rx.spring.domain.Person;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.stereotype.Component;
 
@Component
public class RaoInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
    
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    
        if ("person".equals(beanName) || "student".equals(beanName)) {
    
            System.out.println(beanName + "--->>>InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation....");
        }
        return null;
    }
 
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
    
        if ("person".equals(beanName) || "student".equals(beanName)) {
    
            System.out.println(beanName + "--->>>InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation....");
        }
        return bean instanceof Person;
    }
 
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
    
        System.out.println(beanName + "--->>>InstantiationAwareBeanPostProcessor.postProcessProperties...");
        PropertyValue[] propertyValues = pvs.getPropertyValues();
        for (PropertyValue propertyValue : propertyValues) {
    
            if ("name".equals(propertyValue.getName())) {
    
                propertyValue.setConvertedValue("改后rx");
            }
        }
        return pvs;
    }
}

RaoBeanPostProcessor


package com.rx.spring.beanpostprocessor;
 
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
 
@Component
public class RaoBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    
        if ("person".equals(beanName) || "student".equals(beanName)) {
    
            System.out.println(beanName + "--->>>BeanPostProcessor.postProcessBeforeInitialization...");
        }
        return bean;
    }
 
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    
        if ("person".equals(beanName) || "student".equals(beanName)) {
    
            System.out.println(beanName + "--->>>BeanPostProcessor.postProcessAfterInitialization....");
        }
        return bean;
    }
}

spring.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 id ="person" class="com.rx.spring.domain.Person" init-method="raoInitMethod" destroy-method="raoDestroyMethod">
        <property name="name" value="rx"/>
        <property name="address" value="beijing"/>
        <property name="tel" value="157********"/>
    </bean>
 
    <bean id ="student" class="com.rx.spring.domain.Student" init-method="raoInitMethod" destroy-method="raoDestroyMethod">
        <property name="username" value="rx"/>
        <property name="password" value="1234"/>
    </bean>
 
</beans>

运行结果:

在这里插入图片描述
在这里插入图片描述

运行结果符合预期,成功验证了之前的结论!!!

原创不易,转载请附上本页面链接

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_43244698/article/details/109338537

智能推荐

组件三大属性,state,props,refs_组件自带的属性-程序员宅基地

文章浏览阅读673次。一,组件实例三大属性(1)state查看状态:在写好的组件实例上有一个属性,state,就代表这个组件的状态。接下来我们写一个有状态的组件:<body> <div id="test"></div> <script type="text/babel"> // 创建组件 class Component extends React.Component { // 初始化,调_组件自带的属性

yii2框架-yii2的组件和服务定位器(四)_yii2 unknown component id: db-程序员宅基地

文章浏览阅读4.4k次,点赞3次,收藏4次。上一节主要是分析了yii2的自动加载函数,下面在分析一下yii2的核心组件与服务定位器。其实yii2的核心组件主要有以下://日志组件'log' => ['class' => 'yii\log\Dispatcher'],//视图组件,这个组件代表视图文件中的$this'view' => ['class' => 'yii\web\View'],//格式化组件,将一些输出按照一_yii2 unknown component id: db

SystemVerilog总结_systemverilog语法-程序员宅基地

文章浏览阅读6.9k次,点赞24次,收藏315次。基于SV绿皮书的systemverilog总结_systemverilog语法

2024 EasyRecovery三分钟帮你恢复 电脑硬盘格式化-程序员宅基地

文章浏览阅读1.5k次,点赞43次,收藏13次。在格式化过程中,硬盘上的所有数据并没有被擦除,而是被标记为可覆盖状态,这意味着只要数据没有被新数据完全覆盖,仍然有可能各种技术手段对其进行恢复性操作。需要注意的是,在对硬盘进行恢复性操作之前,我们需要让硬盘保持刚刚格式化的数据状态,不要再做任何删除或者存储的动作,以免对原数据产生覆盖。如果遇到电脑硬盘被格式化后,第一步要做的是暂停对该硬盘的使用,其次是搜索并下载一款专业性强且口碑不错的数据恢复软件自主恢复数据。4.等待软件扫描结束,从扫描结果中选择需要被恢复的数据后单击“恢复”即可找回丢失的数据。_easyrecovery

基于微信小程序的微信平台签到系统的设计与实现(源码+lw+部署文档+讲解等)_微信扫码签到小程序开发-程序员宅基地

文章浏览阅读999次,点赞15次,收藏20次。博主介绍:全网粉丝15W+,CSDN特邀作者、211毕业、高级全栈开发程序员、大厂多年工作经验、码云/掘金/华为云/阿里云/InfoQ/StackOverflow/github等平台优质作者、专注于Java、小程序技术领域和毕业项目实战,以及程序定制化开发、全栈讲解、就业辅导精彩专栏 推荐订阅2023-2024年最值得选的微信小程序毕业设计选题大全:100个热门选题推荐2023-2024年最值得选的Java毕业设计选题大全:500个热门选题推荐Java精品实战案例《500套》_微信扫码签到小程序开发

基于SpringBoot+Vue+uniapp的实验室考勤管理系统的详细设计和实现(源码+lw+部署文档+讲解等)-程序员宅基地

文章浏览阅读587次,点赞14次,收藏9次。博主介绍:全网粉丝15W+,CSDN特邀作者、211毕业、高级全栈开发程序员、大厂多年工作经验、码云/掘金/华为云/阿里云/InfoQ/StackOverflow/github等平台优质作者、专注于Java、小程序技术领域和毕业项目实战,以及程序定制化开发、全栈讲解、就业辅导精彩专栏 推荐订阅2023-2024年最值得选的微信小程序毕业设计选题大全:100个热门选题推荐2023-2024年最值得选的Java毕业设计选题大全:500个热门选题推荐Java精品实战案例《500套》

随便推点

5000字超干货,新中国成立70年人口流动迁移的特征与趋势可视化!-程序员宅基地

文章浏览阅读1.2k次。‍‍来源:城市数据派转自:上海数据分析‍‍大家好,我是小z今天给大家分享一篇新中国成立70年人口流动迁移的文章1 改革开放前的人口流动迁移特征改革开放前,我国人口迁移规模较改革开放后而言,..._国内人口迁移数据挖掘与可视化

快手app抓包方案常见的初探_快手抓包无网络-程序员宅基地

文章浏览阅读9k次,点赞3次,收藏14次。作为一个快手资深用户,每天使用快手app看老铁直播,出于兴趣,曾经对快手接口进行过简单研究,年前写过一个小玩意发送弹幕发送跟老铁互喷!前两天想看下是否好使,发现快手app新版本限制抓包了,那就先研究一下快手app抓包吧!经过一下午的研究,发现可以通过一下三种方式,对app就行http抓包!使用的工具: charles, root过的安卓手机一台 不同版本的快手apk1,降低apk版本[快手版本6.8]进过测试,发现降低版本可以进行抓包,测试版本6.8.0抓包通过!但缺点也很明显,apk过于老旧,_快手抓包无网络

万能数据恢复大师官方版_数据恢复大师新版-程序员宅基地

文章浏览阅读1.2k次。万能数据恢复大师是非常强大的数据恢复软件。它能够恢复误删除、误格式化、U盘\手机储存卡、分区丢失后的数据,及时拯救您宝贵的数据。_数据恢复大师新版

python distribute是什么-程序员宅基地

文章浏览阅读388次,点赞8次,收藏9次。你可以自己找到最新版本的Distribute,在这里https://pypi.python.org/pypi/distribute。可以通过distribute_setup.py 脚本来安装Distribute,也可以通过easy_install, pip,源文件来安装,不过使用distribute_setup.py来安装是最简单和受欢迎的方式。Distribute是对标准库disutils模块的增强,我们知道disutils主要是用来更加容易的打包和分发包,特别是对其他的包有依赖的包。

C语言printf函数-程序员宅基地

文章浏览阅读1.7w次,点赞124次,收藏262次。C语言printf函数_c语言printf函数

oracle的faq(zz)_dbms_repcat_internal_package-程序员宅基地

文章浏览阅读1.1k次。第一部分、SQL&PL/SQL[Q]怎么样查询特殊字符,如通配符%与_[A]select * from table where name like A/_% escape /[Q]如何插入单引号到数据库表中[A]可以用ASCII码处理,其它特殊字符如&也一样,如insert into t values(i||chr(39)||m); -- chr(39)代表字符或者用两个单引_dbms_repcat_internal_package