文前说明
作为码农中的一员,需要不断的学习,我工作之余将一些分析总结和学习笔记写成博客与大家一起交流,也希望采用这种方式记录自己的学习之旅。
本文仅供学习交流使用,侵权必删。
不用于商业目的,转载请注明出处。
1. 概述
- 初始化 bean 的方法的调用流程(主要还是根据 用户设定 的来进行初始化)的第一个步骤就是激活 Aware 方法。
2. Aware 接口
- org.springframework.beans.factory.Aware 接口。
public interface Aware {
}
-
Aware
接口为 Spring 容器的核心接口,是一个具有标识作用的接口,实现了该接口的 bean 是具有被 Spring 容器通知的能力,通知的方式是采用 回调 的方式。 -
Aware
接口是一个空接口,实际的方法签名由各个子接口确定。- 该接口通常只会有一个接收单参数的 set 方法,该 set 方法的命名方式为 set + 去掉接口名中的
Aware
后缀,即 XxxAware 接口,则方法定义为 setXxx(),例如BeanNameAware
(setBeanName),ApplicationContextAware
(setApplicationContext)。
- 该接口通常只会有一个接收单参数的 set 方法,该 set 方法的命名方式为 set + 去掉接口名中的
-
Aware
的子接口需要提供一个 setXxx 方法,即Aware
类接口的 setXxx 方法就是设置 xxx 属性值。
invokeAwareMethods
// AbstractAutowireCapableBeanFactory.java
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
// BeanNameAware
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
// BeanClassLoaderAware
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
// BeanFactoryAware
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
- 判断 bean 实例是否属于
Aware
接口的范畴,如果是则调用实例的 setXxx() 方法给实例设置 xxx 属性值(主要设置 beanName,beanClassLoader、BeanFactory 中三个属性值)。
3. Aware 子类
- Spring 提供了诸多
Aware
接口,用于辅助 Spring Bean 以编程的方式调用 Spring 容器,通过实现这些接口,可以增强 Spring Bean 的功能。
接口 | 说明 |
---|---|
LoadTimeWeaverAware | 加载 Spring Bean 时织入第三方模块,如 AspectJ。 |
BeanClassLoaderAware | 加载 Spring Bean 的类加载器。 |
BootstrapContextAware | 资源适配器 BootstrapContext,如 JCA,CCI。 |
ResourceLoaderAware | 底层访问资源的加载器。 |
BeanFactoryAware | 声明 BeanFactory。 |
PortletConfigAware | PortletConfig。 |
PortletContextAware | PortletContext。 |
ServletConfigAware | ServletConfig。 |
ServletContextAware | ServletContext。 |
MessageSourceAware | 国际化。 |
ApplicationEventPublisherAware | 应用事件。 |
NotificationPublisherAware | JMX 通知。 |
BeanNameAware | 声明 Spring Bean 的名字。 |
3.1 用例
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
public class Test implements BeanNameAware, BeanFactoryAware, BeanClassLoaderAware, ApplicationContextAware {
private String beanName;
private BeanFactory beanFactory;
private ClassLoader classLoader;
private ApplicationContext applicationContext;
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("调用了 BeanClassLoaderAware 的 setBeanClassLoader 方法");
this.classLoader = classLoader;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("调用了 BeanFactoryAware 的 setBeanFactory 方法");
this.beanFactory = beanFactory;
}
@Override
public void setBeanName(String name) {
System.out.println("调用了 BeanNameAware 的 setBeanName 方法");
this.beanName = name;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("调用了 ApplicationContextAware 的 setApplicationContext 方法");
this.applicationContext = applicationContext;
}
public void display() {
System.out.println("beanName:" + beanName);
System.out.println("是否为单例:" + beanFactory.isSingleton(beanName));
System.out.println("系统环境为:" + applicationContext.getEnvironment());
}
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
Test test = (Test) applicationContext.getBean("test");
test.display();
}
}
- Spring 配置文件。
<?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="test" class="Test"></bean>
</beans>
- 运行输出。
调用了 BeanNameAware 的 setBeanName 方法
调用了 BeanClassLoaderAware 的 setBeanClassLoader 方法
调用了 BeanFactoryAware 的 setBeanFactory 方法
调用了 ApplicationContextAware 的 setApplicationContext 方法
beanName:test
是否为单例:true
系统环境为:StandardEnvironment {activeProfiles=[], defaultProfiles=[default], propertySources=[MapPropertySource {name='systemProperties'}, SystemEnvironmentPropertySource {name='systemEnvironment'}]}
网友评论