自定义组件中如何注入Spring底层的组件

news/2024/11/23 20:48:26/

1.概述

自定义的组件要想使用Spring容器底层的一些组件,比如ApplicationContext(IOC容器)、底层的BeanFactory等等,那么只需要让自定义组件实现XxxAware接口即可。此时,Spring在创建对象的时候,会调用XxxAware接口中定义的方法注入相关的组件

2.XxxAware接口概览

在Spring中,类似于ApplicationContextAware接口的设计有很多,本质上,Spring中形如XxxAware这样的接口都继承了Aware接口,我们来看下Aware接口的源码,如下所示:

package org.springframework.beans.factory;public interface Aware {}

Aware接口是Spring 3.1版本中引入的接口,在Aware接口中,并未定义任何方法

3.XxxAware接口案例

3.1.ApplicationContextAware接口

通过ApplicationContextAware接口我们可以获取到IOC容器

创建一个Red类,实现ApplicationContextAware接口,并在实现的setApplicationContext()方法中将ApplicationContext输出,如下所示:

package com.tianxia.springannotation.entity;import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;/*** 红色类* @author liqb* @date 2023-04-23 15:43**/
@Component
public class Red implements ApplicationContextAware{private ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {System.out.println("传入的IOC:" + applicationContext);this.applicationContext = applicationContext;}
}

3.2.BeanNameAware接口

通过BeanNameAware接口获取到当前bean在Spring容器中的名称,如下所示:

package com.tianxia.springannotation.entity;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.stereotype.Component;/*** 红色类* @author liqb* @date 2023-04-23 15:43**/
@Component
public class Red implements ApplicationContextAware, BeanNameAware {private ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {System.out.println("传入的IOC:" + applicationContext);this.applicationContext = applicationContext;}@Overridepublic void setBeanName(String name) {System.out.println("当前bean的名字:" + name);}
}

3.3.EmbeddedValueResolverAware

通过EmbeddedValueResolverAware接口能够获取到String值解析器,如下所示:

package com.tianxia.springannotation.entity;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.stereotype.Component;
import org.springframework.util.StringValueResolver;/*** 红色类* @author liqb* @date 2023-04-23 15:43**/
@Component
public class Red implements ApplicationContextAware, BeanNameAware, EmbeddedValueResolverAware {private ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {System.out.println("传入的IOC:" + applicationContext);this.applicationContext = applicationContext;}@Overridepublic void setBeanName(String name) {System.out.println("当前bean的名字:" + name);}@Overridepublic void setEmbeddedValueResolver(StringValueResolver resolver) {String resolveStringValue = resolver.resolveStringValue("你好,${os.name},我的年龄是#{20*18}");System.out.println("解析的字符串:" + resolveStringValue);}
}

StringValueResolver会解析那些String类型的值的,如果这个String类型的值里面有一些占位符,那么也会把这些占位符给解析出来,最后返回一个解析后的值

运行测试方法,输出的结果信息如下所示:

/*** 测试方法* @author liqb* @date 2023-05-08 11:51*/
@Test
public void test03() {AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAutowired.class);Color color = (Color) applicationContext.getBean("color02");System.out.println(color);applicationContext.close();
}

在这里插入图片描述

3.XxxAware原理

XxxAware接口的底层原理是由XxxAwareProcessor实现类实现的,也就是说每一个XxxAware接口都有它自己对应的XxxAwareProcessor实现类。 例如,ApplicationContextAware接口的底层原理就是由ApplicationContextAwareProcessor类实现的。从ApplicationContextAwareProcessor类的源码可以看出,其实现了BeanPostProcessor接口,本质上是一个后置处理器。

class ApplicationContextAwareProcessor implements BeanPostProcessor {private final ConfigurableApplicationContext applicationContext;private final StringValueResolver embeddedValueResolver;
}

分析ApplicationContextAware接口的原理为例,看看Spring是怎么将ApplicationContext对象注入到Red类中的

在Red类的setApplicationContext()方法上打一个断点,并运行测试方法,如下所示:

在这里插入图片描述

ApplicationContext对象已经注入到Red类的setApplicationContext()方法中了

然后定位到了postProcessBeforeInitialization()方法

在这里插入图片描述

在这里插入图片描述

postProcessBeforeInitialization()方法所在的类就是ApplicationContextAwareProcessor,在postProcessBeforeInitialization()方法中调用的invokeAwareInterfaces()方法,如下所示

在这里插入图片描述

Red类实现了ApplicationContextAware接口后,Spring为啥会将ApplicationContext对象自动注入到setApplicationContext()方法中就是如此


http://www.ppmy.cn/news/63657.html

相关文章

Netty基础(二)

1.Netty高性能架构设计 1.1.线程模型基本介绍 1>.不同的线程模式,对程序的性能有很大影响,为了搞清Netty线程模式,我们来系统的讲解下各个线程模式,最后看看Netty线程模型有什么优越性; 2>.目前存在的线程模型有: ①.传统阻塞I/O服务模型; ②.Reactor(反应器)模式; 3…

Android 套壳本地html 生成apk

参考了:https://www.jianshu.com/p/ebf7948f3796 首页是前端会给到你html文件 目录基本上是这样的 image.png 步骤1: 创建assets目录 用户安卓studio 新合建工程就不写了 ,下面的图是如何创建assets资源目录: image.png image.png 步骤2:拷贝…

【华为OD机试真题 Python】简单的解压缩算法 (100%通过)

前言:本专栏将持续更新互联网大厂机试真题,并进行详细的分析与解答,包含完整的代码实现,希望可以帮助到正在努力的你。关于大厂机试流程、面经、面试指导等,如有任何疑问,欢迎联系我,wechat:steven_moda;email:nansun0903@163.com;备注:CSDN。 题目描述 现需要实现…

使用 Vert.x 异步发送HTTP长阻塞请求来提高并发响应

假设我们开发了一个必须与其他HTTP服务来交互的服务。不幸的是,这些HTTP服务速度慢且是阻塞的。 它可能是一个非常慢的遗留HTTP服务或我们必须使用的一些阻塞 API。无论如何,我们无法控制它。在这里,我们将调用两个HTTP API。其中一个将阻塞…

8.最长公共子序列问题

title: 8.最长公共子序列问题 date: 2023-05-02 15:52:40 categories: 大学课程内容大二下算法分析基础 8.最长公共子序列问题 【问题描述】 若给定序列X{x1,x2,…,xm},则另一序列Z{z1,z2,…,zk},是X的子序列是指存在一个严格递增下标序列{i1,i2,…,i…

前端学习之使用JavaScript(3)

BOM BOM BOM(Browser Object Model,浏览器对象模型)是JavaScript中用于与浏览器窗口及其元素进行交互的API。 BOM提供了一系列对象,这些对象代表了浏览器的不同部分,使得开发者能够控制浏览器的各种功能,如…

qt creator添加build步骤删除某个文件

参考:https://blog.csdn.net/weixin_44436546/article/details/113587115 1. windows下配置: 添加build步骤;在commad栏输入cmd,会弹出C:\Windows\system32\cmd.exe;在Arguments栏输入/c release\upgrade.o;Working …

原型模式--深拷贝和浅拷贝

定义 Specify the kind of objects to create using a prototypical instance, and create new objects by copying this prototype. (使用原型实例指定将要创建的对象类型,通过复制这个实例创建新的对象。) 从定义中我们我们可以发现&#x…