Spring之Bean的生命周期

2023-10-31

BeanFactory 中 Bean的生命周期

在这里插入图片描述
带★的表示为容需要实现的接口,不带星号的表示是bean要实现的接口,因为是BeanFactory,所以只有在getbean方法调用时才会走生命周期

接口 返回值 方法 参数 作用
InstantiationAwareBeanPostProcessor Object postProcessBeforeInstantiation Class beanClass, String beanName 在bean实例化之前调用,返回的Object必须与beanClass相同,返回的object就是当前的bean
boolean postProcessAfterInstantiation Object bean, String beanName 在bean实例化之后调用,如果返回false,则不会进行第四步postProcessProperties和第五步设置初始值
PropertyValues postProcessProperties PropertyValues pvs, Object bean, String beanName 在bean实例化之后,在bean赋值前调用,pvs存放的是配置文件里的信息,可以在赋值前进行最后修改
postProcessPropertyValues(新版本已废弃) 在bean实例化之后,在bean赋值前调用
接口 返回值 方法 参数 作用
BeanNameAware void setBeanName name 关联bean名
BeanFactoryAware void setBeanFactory BeanFactory beanFactory 关联bean工厂
InitializingBean void afterPropertiesSet 初始化bean方法
DisposableBean void destroy 销毁bean方法
接口 返回值 方法 参数 作用
BeanPostProcessor Object postProcessBeforeInitialization Object bean, String beanName 不用bean实现的初始化前置方法
Object postProcessAfterInitialization Object bean, String beanName 不用bean实现的初始化后置方法
接口 方法 作用
Ordered getOrder 多个InstantiationAwareBeanPostProcessor 或 BeanPostProcessor 时指定顺序

测试代码

配置文件

<?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="dog" class="com.ke.Dog" init-method="myInit" destroy-method="myDestroy" >
        <property name="name" value="dsbgs"/>
    </bean>
</beans>

InstantiationAwareBeanPostProcessor 接口实现类

public class FactoryLife implements InstantiationAwareBeanPostProcessor{
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInstantiation方法执行");
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInstantiation方法执行");
        return true;
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        MutablePropertyValues p = (MutablePropertyValues) pvs;
        //如果bean有age这个字段则可以设置值,设置不存在的属性会报错
        //p.add("age",16);
        System.out.println("postProcessProperties方法执行");
        return pvs;
    }
    
}

bean相关生命周期设置代码

public class Dog implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
    private String name;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public Dog() {
        System.out.println("初始化");
    }

    public void show(){
        System.out.println("Hello,"+ name );
    }

    //BeanNameAware接口实现
    @Override
    public void setBeanName(String name) {
        System.out.println("setBeanName方法执行");
    }
    //BeanNameAware接口实现
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        BeanFactory beanFactoryTo =  beanFactory;
        System.out.println("setBeanFactory方法执行");
    }
    //InitializingBean接口实现
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet方法执行");
    }
    //DisposableBean接口实现
    @Override
    public void destroy() throws Exception {
        System.out.println("destroy方法执行");
    }

    //配置文件配置的初始化方法
    public void myInit()
    {
        System.out.println("myInit方法执行");
    }
    //配置文件配置的销毁方法
    public void myDestroy()
    {
        System.out.println("myDestroy方法执行");
    }
}

BeanPostProcessor 接口相关实现

public class BeanLife implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization方法执行");
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization方法执行");
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}

使用

public class test {
    public static void main(String[] args) throws IOException {
        ResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();
        Resource resource = pathMatchingResourcePatternResolver.getResource("beans.xml");

        DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(defaultListableBeanFactory);
        xmlBeanDefinitionReader.loadBeanDefinitions(resource);
        //注入生命周期接口实现类
        defaultListableBeanFactory.addBeanPostProcessor(new FactoryLife());
        defaultListableBeanFactory.addBeanPostProcessor(new BeanLife());
        Dog hello = (Dog)defaultListableBeanFactory.getBean("dog");
        //销毁bean
        defaultListableBeanFactory.destroySingleton("dog");
    }
}

输出
在这里插入图片描述

结论

  • InstantiationAwareBeanPostProcessor 接口主要用于容器级别的生命周期控制
  • BeanPostProcessor接口主要用于整体bean的控制
  • Bean类实现的接口,可以针对每个bean进行处理
  • InitDestroyAnnotationBeanPostProcessor 接口可以实现用注解 @PostConstruct@PreDestroy 在Bean 实例创建完成和销毁之前

如果让bean实现接口,不是一个很好的方法,这样类就依赖spring,在其他环境下就无法使用。
BeanNameAware和BeanFactoryAware可以用属性注入的方法来替代。InitializingBean,DisposableBean用配置文件的形式也是相同。BeanPostProcessor接口可以在后面实现AOP的功能。

ApplicationContext中 Bean的生命周期

在这里插入图片描述
ApplicationContext相比beanFactory多了两个接口
BeanFactoryPostProcessor接口和ApplicationContextAware接口,而且不用再用代码注入这些,spring会通过反射自动加载,所以写在配置文件中即可。
baen.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="hello" class="com.ke.Hello">
        <property name="name" value="dsbcql"/>
        <property name="age" value="18"/>
    </bean>
    <!--注入对应的生命周期接口,id随意,class实现对应接口就能注入-->
    <bean id="myBeanFactoryPostProcessor1" class="com.ke.life.ApplicationContextLife"/>
    <bean id="myInstantiationAwareBeanPostProcessor" class="com.ke.life.FactoryLife"/>
    <bean id="myBeanPostProcessor" class="com.ke.life.BeanLife"/>
</beans>

bean(实现ApplicationContextAware ,可以得到applicationContext)

public class Hello implements ApplicationContextAware {
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Hello() {
        System.out.println("初始化");
    }
    public void show(){
        System.out.println("Hello,"+ name );
        System.out.println("Hello,"+ age );
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("实现ApplicationContextAware");
    }
}

BeanFactoryPostProcessor 实现类

public class ApplicationContextLife implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        BeanDefinition hello = beanFactory.getBeanDefinition("hello");
        MutablePropertyValues propertyValues = hello.getPropertyValues();
        propertyValues.add("age",6666);
    }
}

使用

public class test {
    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("beans.xml");
        Hello hello = classPathXmlApplicationContext.getBean("hello",Hello.class);
        hello.show();
    }


}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring之Bean的生命周期 的相关文章

随机推荐

  • ajax获取500,使用Python请求库500获取Ajax Json输出

    import requests import json class Yurtici object baseUrl http www yurticikargo com ajaxRoot1 layouts ArikanliHolding Yur
  • 模板之特化与偏特化

    C 模板 C 模板提供了对逻辑结构相同的数据对象通用行为的定义 这些模板运算对象的类型不是实际的数据类型 而是一种参数化的类型 C 模板分为类模板和函数模板那 类模板示例 template
  • MySQL的binlog功能详解

    什么是binlog binlog日志用于记录所有更新了数据或者已经潜在更新了数据 例如 没有匹配任何行的一个DELETE 的所有语句 语句以 事件 的形式保存 它描述数据更改 binlog作用 因为有了数据更新的binlog 所以可以用于实
  • MySQL主从复制

    1 基础环境配置 1 修改主机名 使用hostnamectl命令修改2台主机的主机名 root localhost hostnamectl set hostname db1 root localhost bash root db1 root
  • 干货-YOLOv5检测烟火

    火灾是一种常见的自然灾害和事故 经常给人们的生命财产安全带来威胁 在人力无法及时发现火灾的情况下 火势可能迅速扩散 造成不可挽回的损失 因此 及时发现火灾并采取有效的救援措施至关重要 利用计算机视觉技术检测火灾具有以下意义 提高火灾检测效率
  • 深入理解Socket套接字:必要的参数详解

    深入理解Socket套接字 必要的参数详解 文章目录 深入理解Socket套接字 必要的参数详解 引言 1 1 简介 1 2 Socket套接字的作用 Socket套接字的创建 2 1 Socket函数 2 2 Socket函数参数详解 S
  • 完美的mysql备份脚本

    转自 https www cnblogs com leffss p 7832047 html bin bash 全备方式 一般在从机上执行 适用于小中型mysql数据库 删除15天以前备份 作者 fafu li 时间 2015 08 10
  • 【全栈开发指南】OAuth2授权获取token调试接口的方式

    在我们实际应用接口的调用调试过程中 需要用到token或者刷新token GitEgg支持OAuth2 0协议进行认证授权 这里介绍说明如何通过Postman获取token和refresh token并进行接口调试 1 使用密码模式获取to
  • win10禁用windows更新

    Windows 10系统中有一项Update Orchestrator Service 更新协调器办事 在当地办事窗口中 我们发现 Update Orchestrator Service 状态的启动类型为灰色 无法进行点击修改 2 禁用Wi
  • ESB产品Oracle数据库升级说明

    ESB企业服务总线平台作为支撑企业综合集成的产品 在应用集成 数据集成 数据治理等解决方案都发挥着非常重要的作用 随着产品和解决方案的不断优化和升级 ESB企业服务总线平台功能需要逐步进行完善 不断提升产品功能的完备性 易用性和全面性 为了
  • 类和对象

    面向对象 类和对象 数据存储方面 变量 只能存储一个 如果内容多了 存储起来需要定义n个变量 麻烦 数组 可以存储一组相同数据类型的数据 数据类型相同 如果用数组存储一个人的信息 比较丰富的信息的话 不太方便 例如 吃货联盟中存储订单和菜品
  • Flowable-ui-modeler和MybatisPlus冲突问题

    启动出现报错 file F code test flowable boot target classes com example flowableboot flowable mapper ProcessModelMapper class r
  • 目录功能详解

    bin usr bin usr local bin 是Binary的缩写 这个目录存放着最经常使用的命令 sbin usr sbin usr local sbin s就是Super User的意思 这里存放的是系统管理员使用的系统管理程序
  • SpringBoot配置多个Redis集群数据源+自定义缓存注解实例

    今天找了半天没找到线程的 网上都是多个Redis示例 最还还是自己想办法实现了 两个Redis集群作为数据源 自定义缓存注解 不会做的是否发现好tm难 都不知道怎么动手 做完之后 发现原理其实特别简单 很容易就能实现 分两部分原理和示例代码
  • 使用pycharm传入初始化环境配置参数(Run configuration)

    在run gt edit configurations 选择项目并填写参数
  • td 字典表_字典表设计

    为什么字典表 存在问题 某些变量在多个地方使用 而且一般是固定的 但是随着系统升级和后期变化 可能需要改变 如果这些变量写死在代码里面将会变得难以维护 所以要将其从代码中抽离出来 一般的业务系统客户端与用户交互的时候都会使用下拉框组件 对于
  • day2作业

    1 列举出3种常见的操作系统 答 操作系统 windows ubuntu MacOS 其内核 windowsNT Linux uniux 2 简述Ubuntu和Linux的关系 答 Ubuntu 乌班图 是一个以桌面应用为主的Linux操作
  • 数据结构C语言版——初始化一个线性表

    问题描述 初始化一个线性表 程序代码 include stdio h include stdlib h define OVERFLOW 0 define OK 1 define LIST INIT SIZE 100 define LISTI
  • bomblab实验-bomb1~6and隐藏关

    bomb1 08048ae0
  • Spring之Bean的生命周期

    文章目录 BeanFactory 中 Bean的生命周期 测试代码 结论 ApplicationContext中 Bean的生命周期 BeanFactory 中 Bean的生命周期 带 的表示为容需要实现的接口 不带星号的表示是bean要实