mini-spring基础篇:IoC(十一):Aware接口

一、Aware接口

代码分支:aware-interface
之前都是基于main分支来追踪源码,从现在开始,我们基于每章开始的代码分支追踪源码。

mini-spring源码作者建议如此,这样阅读难度会更小。

Aware是感知、意识的意思,Aware接口是标记性接口,其实现子类能感知容器相关的对象。常用的Aware接口有BeanFactoryAware和ApplicationContextAware,分别能让其实现者感知所属的BeanFactory和ApplicationContext。

让实现BeanFactoryAware接口的类能感知所属的BeanFactory,实现比较简单,查看AbstractAutowireCapableBeanFactory#initializeBean前三行。

实现ApplicationContextAware的接口感知ApplicationContext,是通过BeanPostProcessor。由bean的生命周期可知,bean实例化后会经过BeanPostProcessor的前置处理和后置处理。定义一个BeanPostProcessor的实现类ApplicationContextAwareProcessor,在AbstractApplicationContext#refresh方法中加入到BeanFactory中,在前置处理中为bean设置所属的ApplicationContext。

改用dom4j解析xml文件。

至止,bean的生命周期如下:

测试:

spring.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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
	         http://www.springframework.org/schema/beans/spring-beans.xsd
		 http://www.springframework.org/schema/context
		 http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <bean id="helloService" class="org.springframework.test.service.HelloService"/>

</beans>
java 复制代码
public class HelloService implements ApplicationContextAware, BeanFactoryAware {

	private ApplicationContext applicationContext;

	private BeanFactory beanFactory;

	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		this.beanFactory = beanFactory;
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}

	public ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	public BeanFactory getBeanFactory() {
		return beanFactory;
	}
}
java 复制代码
public class AwareInterfaceTest {

	@Test
	public void test() throws Exception {
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml");
		HelloService helloService = applicationContext.getBean("helloService", HelloService.class);
		assertThat(helloService.getApplicationContext()).isNotNull();
		assertThat(helloService.getBeanFactory()).isNotNull();
	}
}

二、源码追踪

可以看到HelloService实现了两个接口BeanFactoryAware、ApplicationContextAware。这两个接口都要实现他们各自的方法,分别是设置ApplicationContext、BeanFactory。这两个都是ioc容器。

BeanFactory多用于spring本身,ApplicationContext多用于我们这些使用者。

2.1 BeanFactoryAware源码追踪








DefaultListableBeanFactory对象类图:

2.2 ApplicationContextAware源码追踪

前8步,和【10.1.1】一毛一样,我们从第9步开始看:



2.3 设置完BeanFactory和ApplictionContext之后呢?干了什么

暂时还不懂。

三、应用场景

我有一个类,不归spring管理,但我又想在这个类里操作spring,那么我该如何操作?

3.1 SpringUtil源码:

其中,BeanFactoryPostProcessor是用来修改BeanDefinition的。

3.2 SpringUtil中设计到BeanFactoryPostProcessor部分的源码

实现BeanFactoryPostProcessor接口,需要重写这个方法:

它的入参,要注入一个ConfigurableListableBeanFactory对象。这个其实就是我们前面看到的DefaultListableBeanFactory对象。可以看前面的类图:


这里的对象,就包括了SpringUtil对象!

猜测:

读到这里,我猜测SpringUtil是不是应该被加入到了spring容器里,我猜大概率是通过spi的方式加入进去的。

查看hutool源码,果然印证了我的猜测:

多废话一句,对第【5】步做一个补充:

废话说完了,继续第6步:

只是我们之前自定义的CustomBeanFactoryPostProcessor:

hutool的SpringUtil:

相关推荐
AM越.3 小时前
Java设计模式超详解——抽象工厂设计模式(含UML图)
java·设计模式·uml
嵌入式小能手3 小时前
飞凌嵌入式ElfBoard-文件I/O的深入学习之文件锁
java·服务器·学习
Predestination王瀞潞3 小时前
Java EE开发技术 (报错解决 请求的资源[/Bank/$%7BpageContext.request.contextPath%7D/login]不可用)
java·java-ee
Sahadev_3 小时前
GitHub 一周热门项目速览 | 2025年12月08日
java·大数据·人工智能·安全·ai作画
Jaxson Lin3 小时前
Java编程进阶:打造专属于你的背单词软件V1.0
java·开发语言
7ioik3 小时前
什么是栈帧?
java
路边草随风3 小时前
java实现发布flink k8s application模式作业
java·大数据·flink·kubernetes
whltaoin3 小时前
【Java SE】Java IO 类常用方法大全:从字节流到 NIO 的核心 API 汇总
java·开发语言·api·nio
编程修仙3 小时前
第二篇 SpringBoot项目启动流程
java·spring boot·后端