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

news2024/11/17 3:49:31

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();

    }

}

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

气膜建筑的施工对周边环境影响大吗?—轻空间

随着城市化进程的加快&#xff0c;建筑行业的快速发展也带来了环境问题。噪音、灰尘和建筑废料等对周边居民生活和生态环境造成了不小的影响。因此&#xff0c;选择一种环保高效的施工方式变得尤为重要。气膜建筑作为一种新兴的建筑形式&#xff0c;其施工过程对周边环境的影响…

python——网络编程

流程图 面向连接的套接字 面向连接的通信提供序列化的、可靠的和不重复的数据交付&#xff0c;而没有记录边界。主要的协议是传输控制协议&#xff08;TCP&#xff09;; TCP套接字&#xff0c;在python中&#xff0c;必须使用SOCK_STREAM作为套接字类型 tcp的特点 面向连接…

工业机器视觉系统如何实现精准检测?

机器视觉系统是指利用机器替代人眼做出各种测量和判断。一种比较复杂的系统。大多数系统监控对象都是运动物体&#xff0c;系统与运动物体的匹配和协调动作尤为重要&#xff0c;所以给系统各部分的动作时间和处理速度带来了严格的要求。在某些应用领域&#xff0c;例如机器人、…

C++高级 - 接口模板

目录 一. 接口 二. 模板 一. 接口 接口通常是通过抽象类或纯虚函数来实现的。 以下是一个使用抽象类来定义接口的示例代码&#xff1a; #include <iostream>class Interface { public:virtual void operation() 0; // 纯虚函数定义接口 };class ConcreteClass : pu…

网络安全||信息加解密技术以及密钥管理技术

一、信息加解密技术 对称加密 对称加密&#xff08;又称为私人密钥加密/共享密钥加密&#xff09;&#xff1a;加密与解密使用同一密钥。特点&#xff1a;加密强度不高&#xff0c;但效率高&#xff1b;密钥分发困难。&#xff08;大量明文为了保证加密效率一般使用对称加密&…

Three.js的阴影技术,创建逼真效果的必备!

three.js是一个流行的用于创建和展示3D图形的JavaScript库&#xff0c;它提供了多种阴影技术来增强3D场景的真实感和视觉效果。 一、常用阴影技术 1. 基于光线的阴影&#xff08;Raytraced Shadows&#xff09;&#xff1a;通过跟踪光线的路径来计算阴影&#xff0c;产生非常…

SylixOS网卡多 IP 配置

概述 网卡多 IP 是指在同一个网络接口上配置和绑定多个 IP 地址。 引进网卡多 IP 的目的主要有以下几个&#xff1a; 提供服务高可用性。通过在同一接口绑定多个 IP 地址&#xff0c;然后在服务端使用这些 IP 地址启动多个服务实例。这样在任意一 IP 出现问题时&#xff0c;可…

el-input实现后缀图标和clearable的兼容,调整el-input clearable与自定义图标展示位置问题

背景&#xff1a;常见的输入框存在两个图标的展示效果都是清空在前搜索或其他图标在后 常见以及最终实现效果&#xff08;清空图标在前&#xff0c;搜索图标在后&#xff09; BUG以及el-input默认效果 问题排查 通过控制台审查元素能够发现&#xff0c;默认的效果是自定义图标…

何为云防护?有何作用

云防护又称云防御。随着Internet互联网络带宽的增加和多种DDOS 黑客工具的不断发布&#xff0c;云计算越演越热&#xff0c;DDOS拒绝服务攻击的实施越来越容易&#xff0c;DDOS攻击事件正在成上升趋势。出于商业竞争、打击报复和网络敲诈等多种因素&#xff0c;导致很多IDC 托管…

避免 PostgreSQL 翻车的关键技巧

PostgreSQL 是一个功能强大的开源关系型数据库管理系统&#xff0c;它以其稳定性和高性能而受到开发者和企业的青睐。然而&#xff0c;在实际操作中&#xff0c;不当的变更管理可能会导致数据库性能下降或系统崩溃。为了避免这种情况&#xff0c;我们提供了以下关键技巧来确保 …

Docker桥接网络分析

前言 《虚拟局域网(VLAN)》一文中描述了虚拟网卡、虚拟网桥的作用&#xff0c;以及通过iptables实现了vlan联网&#xff0c;其实学习到这里自然就会联想到目前主流的容器技术&#xff1a;Docker&#xff0c;因此接下来打算研究一下Docker的桥接网络与此有何异同。 猜测 众所周知…

react基础学习 JSX

JSX的测试网站 Babel Babel 可以测试代码的效果 JSX实现map列表 注意 key不一样&#xff08;使用遍历的时候&#xff09; 简单条件渲染 复杂条件渲染 绑定事件 function App() {const colorse (e)>{console.log("测试点击",e);}const colorse1 (name)>{…

月入30000的软件测试人员,简历是什么样子的?

我们都知道&#xff0c;简历是一个人进入职场的敲门砖。从某种层面来说&#xff0c;简历也像一个人的具象身份证&#xff0c;或者专业资格证。所以&#xff0c;一份简历的好坏&#xff0c;不仅关乎个人的“脸面”&#xff0c;更关乎你是不是一个有“含金量”的技术人员。 所以…

Python爬虫协程批量下载图片

import aiofiles import aiohttp import asyncio import requests from lxml import etree from aiohttp import TCPConnectorclass Spider:def __init__(self, value):# 起始urlself.start_url value# 下载单个图片staticmethodasync def download_one(url):name url[0].spl…

Docker容器开启特权模式

一、问题 1、容器系统中无法使用systemctl命令 即使是开了特权模式&#xff08;--privileged&#xff09; 2、无法通过/sbin/init启动容器 要想在容器中使用systemctl命令&#xff0c;除了要指定--privileged参数外&#xff0c;还需要指定启动参数为/sbin/init&#xff0c;但…

关于protobuf import 在idea中报红色错误解决

首先安装protobuf 插件 protocol 文件引入别的protocol 时报红原因在插件的设置&#xff0c;它并不知道去哪找&#xff0c;只需要配置下protobuf的所在目录即可

【成品设计】基于单片机的智慧交通控制系统设计

《基于单片机的智慧交通控制系统设计》 所需器件&#xff1a; STM32最小系统板。按键模块。红黄绿LED灯柱。距离传感器。OLED屏幕。语音识别模块。 整体功能&#xff1a; 本文介绍了一种基于单片机的智慧交通控制系统设计。该系统集成了多种传感器、控制器和执行器&#xf…

【成品设计】基于USB接口的指纹图像采集与处理系统设计

《基于USB接口的指纹图像采集与处理系统设计》 所需器件&#xff1a; STM32F429阿波罗开发板。ATK-AS608 模块指纹识别模块。USB转TTL模块。 整体功能&#xff1a; 实现指纹的采集录入。实现指纹的对比&#xff0c;并展示对比结果&#xff0c;用LED灯和蜂鸣器提示。指纹信息…

云原生下的数据协调艺术:etcd存储系统解析

目录 一、分布式存储简介 二、etcd介绍 三、etcd架构 四、etcd集成实践 一、分布式存储简介 随着云原生与容器化技术的兴起&#xff0c;分布式系统的复杂性大大增加。分布式系统面临一系列问题&#xff0c;比如部署复杂、响应时间慢、运维复杂等&#xff0c;其中最根本的问…

MySQL数据库整体知识点简述

目录 第一章&#xff1a;数据库系统概述 第二章&#xff1a;信息与数据模型 第3章 关系模型与关系规范化理论 第四章——数据库设计方法 第六-七章——MySQL存储引擎与数据库操作管理 第九章——索引 第10章——视图 第11章——MySQL存储过程与函数 第12章——MySQL 触…