Aware 简介
Spring中提供了一些以Aware结尾的接口,实现了Aware接口的bean在被初始化之后,可以获取相应资源。比如BeanNameAware之类的以Aware结尾的接口,这个接口获取的资源就是以BeanName相关的。
通过Aware接口,可以对Spring相应资源进行操作(一定要慎重,因为获取的资源可能是IOC的核心资源)。
为对Spring进行简单的扩展提供了方便的接口。
ApplicationContextAware会向实现了这个接口的Bean提供ApplicationContext,也就是IOC容器的上下文的信息。当然,实现了这个接口的Bean必须配置到bean的配置文件中去,并且由Spring的Bean容器去加载,这样才能实现这样的效果。
BeanNameAware类似,它会提供一个关于BeanName定义的这样一些内容。
例子 Spring中各个Aware接口,以及这些接口的主要应用场景。
1. ApplicationContextAware
ApplicationContextAware接口可以让Bean获取到ApplicationContext对象,通过这个对象,我们可以获取Spring容器中的其他Bean实例或一些组件。常见的应用场景包括:
- 在Web项目中获取ServletContext
- 获取国际化信息
- 获取Scheduler等定时任务
示例代码:
public class MyBean implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public void doSomething() {
// 获取其他的Bean实例或其他的组件
OtherBean otherBean = applicationContext.getBean("otherBean", OtherBean.class);
// ...
}
}
2. BeanFactoryAware
BeanFactoryAware接口可以让Bean获取到BeanFactory对象,通过这个对象,我们可以获取Spring容器中的Bean实例或一些组件。常见的应用场景包括:
- 获取Spring容器中的Bean实例
- 手动注册BeanDefinition
示例代码:
public class MyBean implements BeanFactoryAware {
private BeanFactory beanFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
public void doSomething() {
// 获取其他的Bean实例或其他的组件
OtherBean otherBean = beanFactory.getBean("otherBean", OtherBean.class);
// ...
}
}
3. MessageSourceAware
MessageSourceAware接口可以让Bean获取到MessageSource对象,通过这个对象,我们可以方便地进行国际化操作。常见的应用场景包括:
获取国际化信息
public class MyBean implements MessageSourceAware {
private MessageSource messageSource;
@Override
public void setMessageSource(MessageSource messageSource) {
this.messageSource = messageSource;
}
public void doSomething() {
// 获取国际化信息
String message = messageSource.getMessage("key", null, Locale.getDefault());
// ...
}
}
等等
在使用Aware接口时,需要注意避免循环依赖和过度依赖的问题。另外,Aware接口的实现可以通过XML、注解或编程方式来实现
源码解析
我们先了解什么是BeanPostProcessor,是在创建Bean之前以及创建Bean之后的一种后置处理器,这里就简单的讲一下这个,就是在我们使用的这些注解,例如:@Async (异步执行),@Bean,@Component、@Autowired、@PropertySource等等都需要经过BeanPostProcessor去处理才能加载到容器当中,
先看一个示例:
不仅仅有BeanPostProcessor还有BeanDefinitionRegistryPostProcessor(Bean注册器后置处理器)、BeanFactoryPostProcessor(BeanFactory后置处理器),
在处理Aware实现类的时候就会有对应的一个AwareProcessor去处理,我们拿ApplicationContextAware做示例:
我们找到对应的后置处理器ApplicationContextAwareProcessor
因为BeanPostProcessor有两个接口实现,但是只对处理前做内置对象赋值,将对应的对象暴露给我们