(九)Spring教程——ApplicationContext中Bean的生命周期

1.前言

        ApplicationContext中Bean的生命周期和BeanFactory中的生命周期类似,不同的是,如果Bean实现了org.springframework.context.ApplicationContextAware接口,则会增加一个调用该接口方法setApplicationContext()的步骤。

        此外,如果在配置文件中声明了工厂后处理器接口BeanFacotryPostProcessor的实现类,则应用上下文在装载配置文件后、初始化Bean实例之前将调用这些BeanFactoryPostProcessor对配置信息进行加工处理。Spring框架提供了多个工厂后处理器,如CustomEditorConfigurer、PopertyPlaceholderConfigurer等。如果在配置文件中定义了多个工厂后处理器,那么最好让它们实现org.springframework.core.Ordered接口,以便Spring以确定的顺序调用它们。工厂后处理器是容器级的,仅在应用上下文初始化时调用依次,其目的是完成一些配置文件的加工处理工作。

         ApplicationContext和BeanFactory另一个最大的不同之处在于:前者会利用Java反射机制自动识别出配置文件中定义的BeanPostProcessor、InstantiationAwareBeanPostProcessor和BeanFactoryPostProcessor,并自动将它们注册到应用上下文中;而后者需要在代码中通过手工调用addBeanPostProcessor()方法进行注册。这也是为什么在应用开发时普遍使用ApplicationContext而很少使用BeanFactory的原因之一。

       在ApplicationContext中,只需要在配置文件中通过<bean>定义工厂后处理器和Bean后处理器,它们就会按预期的方式运行。

2.创建Car类

        首先,我们对上一篇文章中的Car类稍微修改以下,修改后的代码如下:

package com.example.servlet001.bean;



import org.springframework.beans.BeansException;

import org.springframework.beans.factory.*;

import org.springframework.context.ApplicationContext;

import org.springframework.context.ApplicationContextAware;



// 管理Bean生命周期的接口

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

    private  String brand;

    private String color;

    private int maxSpeed;



    private BeanFactory beanFactory;

    private String beanName;

    public Car(){

        System.out.println("调用Car()构造函数");

    }



    //InitializingBean接口方法

    @Override

    public void afterPropertiesSet() throws Exception {

        System.out.println("调用InitializingBean.afterPropertiesSet()。");

    }



    //BeanNameAware接口方法

    @Override

    public void setBeanName(String s) {

        System.out.println("调用BeanName.setBeanName().");

        this.beanName=s;

    }



    //BeanFactoryAware接口方法

    @Override

    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {

        System.out.println("调用BeanFactoryAware.setBeanFactory()");

        this.beanFactory=beanFactory;

    }



    //DisposableBean接口方法

    @Override

    public void destroy() throws Exception {

        System.out.println("调用DisposableBean.destroy()。");

    }



    //通过<bean>的init-method属性指定的初始化方法

    public void myInit(){

        System.out.println("调用init-method所指定的myInit(),将maxSpeed设置为240。");

        this.maxSpeed=240;

    }



    //通过<bean>的destroy-method属性指定的销毁方法

    public void myDestroy(){

        System.out.println("调用destroy-method所指定的myDestroy()。");

    }



    public String getBrand(){

        return brand;

    }



    public void setBrand(String brand){

        System.out.println("调用setBrand()设置属性。");

        this.brand=brand;

    }



    public String getColor(){

        return color;

    }



    public void setColor(String color){

        this.color=color;

    }



    public int getMaxSpeed(){

        return maxSpeed;

    }



    public void setMaxSpeed(int maxSpeed){

        this.maxSpeed=maxSpeed;

    }



    public void introduce(){

        System.out.println("brand:"+brand+";color:"+color+";maxSpeed:"+maxSpeed);

    }



    @Override

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

        System.out.println("这是ApplicationContextAware的setApplicationContext()方法");

    }

}

3.定义工厂后处理器

        定义一个工厂后处理器,MyBeanFactoryPostProcessor.java,该类的代码如下:

package com.example.servlet001;



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;



/**

 * 工厂后处理器

 */

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    //对car的brand属性配置信息进行“偷梁换柱”的加工操作

    @Override

    public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) throws BeansException {

       BeanDefinition bd=bf.getBeanDefinition("car1");

       bd.getPropertyValues().addPropertyValue("brand","奇瑞QQ");

        System.out.println("调用BeanFactoryPostProcessor.postProcessBeanFactory()");

    }

}

        ApplicationContext在启动时,将首先为配置文件中的每个<bean>生成一个BeanDefinition对象,BeanDefinition是<bean>在Spring容器中的内部表示。当配置文件中所有的<bean>都被解析成BeanDefinition时,ApplicationContext将调用工厂后处理器的方法,因此,有机会通过程序的方式调整Bean的配置信息。在该后处理器中,将car1对应的BeanDefinition进行调整,将brand属性设置为“奇瑞QQ” 。

4.BeanPostProcessror实现类

        此外,还提供了一个BeanPostProcessror实现类,在该类中仅对car Bean进行处理,对配置文件所提供的属性设置值进行判断,并执行相应的“查漏补缺”操作,MyBeanPostProcessor.java的代码如下图所示:

package com.example.servlet001;



import com.example.servlet001.bean.Car;

import org.springframework.beans.BeansException;

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



public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override

    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {

        if(s.equals("car1")){

            Car car = (Car)o;

            if(car.getColor() == null){

                System.out.println("调用MyBeanPostProcessor.postProcessBeforeInitialization(),color为空,设置为默认黑色。");

                car.setColor("黑色");

            }

        }

        return o;

    }



    @Override

    public Object postProcessAfterInitialization(Object o, String s) throws BeansException {

        if(s.equals("car1")){

            Car car = (Car)o;

            if(car.getMaxSpeed() >= 200){

                System.out.println("调用MyBeanPostProcessor.postProcessAfterInitialization(),将maxSpeed调整为200。");

                car.setMaxSpeed(200);

            }

        }

        return o;

    }

}

5.容器级后处理器

      MyInstantiationAwareBeanPostProcessor.java代码如下

package com.example.servlet001;



import org.springframework.beans.BeansException;

import org.springframework.beans.PropertyValues;

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



import java.beans.PropertyDescriptor;



public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {

    @Override

    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {

        if("car1".equals(beanName)){

            System.out.println("MyInstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation");

        }

        return null;

    }



    @Override

    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {

        if("car1".equals(beanName)){

            System.out.println("InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation");

        }

        return true;

    }



    @Override

    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

        if("car1".equals(beanName)){

            System.out.println("InstantiationAwareBeanPostProcessor.postProcessPropertyValues");

        }

        return pvs;

    }

}

6.配置文件

修改resource文件夹下的test.xml配置文件,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"

       xmlns:p="http://www.springframework.org/schema/p"

       xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--这个brand属性的值将会被工厂处理器更改掉-->

    <bean id="car1" name="car1" class="com.example.servlet001.bean.Car"

          init-method="myInit"

          destroy-method="myDestroy"

          p:brand="红旗"

          p:maxSpeed="200"

    />

    <!--容器级声明周期处理-->

    <bean id="myInstantiationAwareBeanPostProcessor" class="com.example.servlet001.MyInstantiationAwareBeanPostProcessor"></bean>

    <!--注册Bean后处理器-->

    <bean id="myBeanPostProcessor"

    class="com.example.servlet001.MyBeanPostProcessor"></bean>

    <!--工厂后处理器-->

    <bean id="myBeanFactoryPostProcessor"

          class="com.example.servlet001.MyBeanFactoryPostProcessor"></bean>



</beans>

7.结果验证

        创建一个Demo1.java类来测试该配置的运行效果,Demo1.java代码如下图所示:

package com.example.servlet001;



import com.example.servlet001.bean.Car;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;



public class Demo1 {

    public static void main(String[] args) {

        ApplicationContext ac = new ClassPathXmlApplicationContext("test.xml");

        Car car=(Car)ac.getBean("car1");

        car.introduce();

    }

}

点击运行后的结果如图所示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/679853.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[数据集][图像分类]蘑菇分类数据集3122张215类别

数据集类型&#xff1a;图像分类用&#xff0c;不可用于目标检测无标注文件 数据集格式&#xff1a;仅仅包含jpg图片&#xff0c;每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数)&#xff1a;3122 分类类别数&#xff1a;215 类别名称:[“almond_mushroom”,“amanita…

C# 中文字符串转GBK字节的示例

一、编写思路 在 C# 中&#xff0c;将中文字符串转换为 GBK 编码的字节数组需要使用 Encoding 类。然而&#xff0c;Encoding 类虽然默认并不直接支持 GBK 编码&#xff0c;但是可以通过以下方式来实现这一转换&#xff1a; 1.使用系统已安装的编码提供者&#xff08;如果系统…

【Spring Cloud Alibaba】开源组件Sentinel

目录 什么是Sentinel发展历史与Hystrix的异同 Sentinel可以做什么&#xff1f;Sentinel的功能Sentinel的开源生态Sentinel的用户安装Sentinel控制台预备环境准备Sentinel 分为两个部分:下载地址 项目集成Sentinel创建项目修改依赖信息添加启动注解添加配置信息在控制器类中新增…

Java 新手入门:基础知识点一览

Java 新手入门&#xff1a;基础知识点一览 想要踏入 Java 的编程世界&#xff1f;别担心&#xff0c;这篇文章将用简单易懂的表格形式&#xff0c;带你快速了解 Java 的基础知识点。 一、Java 是什么&#xff1f; 概念解释Java一种面向对象的编程语言&#xff0c;拥有跨平台、…

最新PHP众筹网站源码 支持报名众筹+商品众筹+公益众筹等多种众筹模式 含完整代码包和部署教程

在当今互联网飞速发展的时代&#xff0c;众筹模式逐渐成为了创新项目、商品销售和公益活动融资的重要渠道。分享一款最新版的PHP众筹网站源码&#xff0c;支持报名众筹、商品众筹和公益众筹等多种众筹模式。该源码包含了完整的代码包和详细的部署教程&#xff0c;让新手也可以轻…

机器学习:算法到底学到了什么?

梯度下降算法 初始化参数 θ 0 \theta^0 θ0可以训练 MAML Maml和pre-train的区别是Maml用到了标注数据 把不同任务的数据放一起进行训练一个模型&#xff0c;当作Maml的baseline 领域迁移迁移学习 Maml好的原因 优化器也可以被学习 网络架构搜索 数据增强 样本权重分配 除…

创建自己的sdk

要把造轮子当作一种享受 右键class出来这个界面,在里面勾选静态库(.lib) 代码如下,我们要将其封装为一个sdk供别人安装使用 cpp文件如下 头文件如下,namespace可以写在头文件里面声明 生成 将那两个文件移到那个文件夹中 我们拿到生成的这两个文件了 截下来演示怎么导入到另…

docker-compose部署 kafka 3.7 启用账号密码认证

文章目录 1. 部署1.1 创建工作目录1.2 yml文件1&#xff09;文件内容2&#xff09;说明&#xff1a; 1.3 启动 2. 测试2.1 kafkamap搭建&#xff08;测试工具&#xff09;2.2 权限测试 1. 部署 1.1 创建工作目录 创建kafka目录&#xff0c;进入该目录 1.2 yml文件 1&#x…

Docker中搭建likeadmin

一、使用Docker中的docker-compose搭建likeadmin 1.去网址&#xff1a;https://gitee.com/likeadmin/likeadmin_php中下载likeadmin 注册一个giee账号后 点那个克隆下载 按照序号在终端复制粘贴进去。 接着&#xff0c;输入ls 可以发现有一个这个&#xff1a; 里面有一个like…

Cell|3D病理弱监督模型在前列腺癌患者治疗中的应用|顶刊精析·24-06-04

小罗碎碎念 这篇文章我之前分析过一遍&#xff0c;本期在原有基础上进行修改。 在正式阅读之前&#xff0c;小罗友情提醒大家重点关注一下几个方向&#xff1a; 从2D组织切片计算的TLS面积已被验证为多种肿瘤类型的预后和免疫治疗响应的生物标志物&#xff0c;然而在小样本活检…

ToxVidLLM:一个用于检测有害视频的多模态多任务框架

在一个社交媒体平台赋予用户成为内容创作者力量的时代&#xff0c;数字领域见证了前所未有的信息传播激增&#xff0c;到2023年&#xff0c;近82%的互联网流量是视频内容。因此&#xff0c;像抖音和YouTub这样的平台已经成为主要的信息来源。一个显著的统计数据凸显了这些平台的…

38【Aseprite 作图】包子——拆解

1 包子轮廓 2 画包子中间的褶皱&#xff0c;褶皱颜色更深一点&#xff0c;不要直接斜着&#xff0c;而是要连着

3. redis常见部署架构

redis常见部署架构 一、redis常见部署架构1、常见部署架构2、多实例部署2.1 规划安装目录、配置文件2.2.2 编辑实例配置文件2.2.3 启动实例2.2.4 测试数据读写 3、redis主从复制3.1 规划3.2 从服务器配置3.3 验证主从状态3.4 主从角色切换 4、分片集群4.1 原理4.2 分片集群的部…

基于单片机的船舱温度临界报警系统

摘 要 : 针对传统的船舱温度临界报警系统&#xff0c;由于温度监控不到位导致报警不及时的问题&#xff0c;提出一个基于单片机的船舱温度临界报警系统设计。该设计将单片机作为核心控制硬件&#xff0c;控制系统整体电路。同时设计数据采集模块&#xff0c;利用温度测量仪测试…

【vue3|第6期】如何正确地更新和替换响应式对象reactive

日期&#xff1a;2024年6月5日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xff…

Leetcode 第 399 场周赛题解

Leetcode 第 399 场周赛题解 Leetcode 第 399 场周赛题解题目1&#xff1a;3162. 优质数对的总数 I思路代码复杂度分析 题目2&#xff1a;3163. 压缩字符串 III思路代码复杂度分析 题目3&#xff1a;3164. 优质数对的总数 II思路代码复杂度分析 题目4&#xff1a;3165. 不包含相…

C51单片机 串口打印printf重定向

uart.c文件 #include "uart.h"void UartInit(void) //4800bps11.0592MHz {PCON | 0x80; //使能波特率倍速位SMODSCON 0x50; //8位数据,可变波特率。使能接收TMOD & 0x0F; //清除定时器1模式位TMOD | 0x20; //设定定时器1为8位自动重装方式TL1 0xF4; //设…

IPFS节点部署及连接java服务接口

文章目录 引言前言&#xff1a;IPFS网络部署1.下载安装文件2.安装及初始化3.测试上传文件 引入IPFS 依赖包初始化IPFS创建接口类以及实现类创建前端访问的控制类前端设计及验证 引言 该篇文章是记录使用IPFS存储文件与java的Springboot项目连接的过程&#xff0c;前端简单地用…

基于websocket与node搭建简易聊天室

一、前言 上一篇文章介绍了websocket的详细用法与工具类的封装&#xff0c;本篇就基于websocket搭建一个简易实时的聊天室。 在本篇开始之前也可以去回顾一下websocket详细用法&#xff1a;WebSocket详解与封装工具类 二、基于node搭建后台websocket服务 首先确认本机电脑中…

YOLOv8改进 | Conv篇 | 利用YOLOv10提出的C2fUIB魔改YOLOv8(附代码 + 完整修改教程)

一、本文介绍 本文给大家带来的改进机制是利用YOLOv10提出的C2fUIB模块助力YOLOv8进行有效涨点&#xff0c;其中C2fUIB模块所用到的CIB模块是一种紧凑的倒置块结构&#xff0c;它采用廉价的深度卷积进行空间混合&#xff0c;并采用成本效益高的点卷积进行通道混合。本文针对该…