spring 06 Aware 接口
Aware 接口
- Aware 接口及 InitializingBean 接口
- Aware 接口提供了一种【内置】 的注入手段,例如
- BeanNameAware 注入 bean 的名字
- BeanFactoryAware 注入 BeanFactory 容器
- ApplicationContextAware 注入 ApplicationContext 容器
- EmbeddedValueResolverAware 注入 ${} 解析器
- InitializingBean 接口提供了一种【内置】的初始化手段
- 对比
- 内置的注入和初始化不受扩展功能的影响,总会被执行
- 而扩展功能受某些情况影响可能会失效
- 因此 Spring 框架内部的类常用内置注入和初始化
- 拓展功能需要添加相应的后处理器 ,如
context.registerBean(AutowiredAnnotationBeanPostProcessor.class); // 解析 @Autowired、 @Value
context.registerBean(CommonAnnotationBeanPostProcessor.class); // 解析 @Resource、@PostConstruct、@PreDestroy
context.registerBean(ConfigurationClassPostProcessor.class); // 解析 @ComponentScan、 @Bean、 @Import、 @ImportResource
点击查看代码
@Slf4j
public class S06Bean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, EmbeddedValueResolverAware,InitializingBean {
/**
* 注入 Bean 的名字
* @param s Bean 的名字
*/
@Override
public void setBeanName(String s) {
log.info("当前 Bean" + this + "名字是" + s);
}
/**
* 初始化
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
}
/**
* 注入 BeanFactory 容器
* @param beanFactory
* @throws BeansException
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
log.info("当前 Bean" + this + " BeanFactory 是" + beanFactory);
}
/**
*注入 ApplicationContext 容器
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
log.info("当前 Bean" + this + " ApplicationContext 是 " + applicationContext);
}
/**
* 注入 ${} 解析器
* @param resolver
*/
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
}
}
配置类 @Autowired 失效分析
Java 配置类不包含 BeanFactoryPostProcessor 的情况
sequenceDiagram
participant ac as ApplicationContext
participant bfpp as BeanFactoryPostProcessor
participant bpp as BeanPostProcessor
participant config as Java配置类
ac ->> bfpp : 1. 执行 BeanFactoryPostProcessor
ac ->> bpp : 2. 注册 BeanPostProcessor
ac ->> +config : 3. 创建和初始化
bpp ->> config : 3.1 依赖注入扩展(如 @Value 和 @Autowired)
bpp ->> config : 3.2 初始化扩展(如 @PostConstruct)
ac ->> config : 3.3 执行 Aware 及 InitializingBean
config -->> -ac : 3.4 创建成功
Java 配置类包含 BeanFactoryPostProcessor 的情况,因此要创建其中的 BeanFactoryPostProcessor 必须提前创建 Java 配置类,而此时的 BeanPostProcessor 还未准备好,导致 @Autowired 等注解失效
sequenceDiagram
participant ac as ApplicationContext
participant bfpp as BeanFactoryPostProcessor
participant bpp as BeanPostProcessor
participant config as Java配置类
ac ->> +config : 3. 创建和初始化
ac ->> config : 3.1 执行 Aware 及 InitializingBean
config -->> -ac : 3.2 创建成功
ac ->> bfpp : 1. 执行 BeanFactoryPostProcessor
ac ->> bpp : 2. 注册 BeanPostProcessor
对应代码
@Configuration
public class MyConfig1 {
private static final Logger log = LoggerFactory.getLogger(MyConfig1.class);
@Autowired
public void setApplicationContext(ApplicationContext applicationContext) {
log.debug("注入 ApplicationContext");
}
@PostConstruct
public void init() {
log.debug("初始化");
}
@Bean // ⬅️ 注释或添加 beanFactory 后处理器对应上方两种情况
public BeanFactoryPostProcessor processor1() {
return beanFactory -> {
log.debug("执行 processor1");
};
}
}
注意
解决方法:
- 用内置依赖注入和初始化取代扩展依赖注入和初始化
- 用静态工厂方法代替实例工厂方法,避免工厂对象提前被创建
点击查看代码
@Slf4j
public class S06Config1 implements InitializingBean, BeanNameAware, ApplicationContextAware {
@Autowired
public void getApplicationContext(ApplicationContext applicationContext) {
log.info("@Autowired 注入的 ApplicationContext 是" + applicationContext);
}
@PostConstruct
public void init() {
log.info("@PostConstruct 初始化");
}
@Override
public void setBeanName(String s) {
log.info("当前 Bean" + this + "名字是" + s);
}
@Override
public void afterPropertiesSet() throws Exception {
log.info(this + "初始化。。。");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
log.info("当前 Bean" + this + " ApplicationContext 名字是" + applicationContext);
}
@Bean
public BeanFactoryPostProcessor getBeanFactoryPostProcessor() {
return b ->{
log.info("执行 BeanFactoryPostProcessor");
};
}
//用静态工厂方法代替实例工厂方法,避免工厂对象提前被创建
// @Bean
// public static BeanFactoryPostProcessor getBeanFactoryPostProcessor() {
// return b ->{
// log.info("执行 BeanFactoryPostProcessor");
// };
// }
}