Aware和InitializingBean接口的作用
- BeanNameAware:注入bean的名字
- BeanFactoryAware:注入BeanFactory容器
- ApplicationContextAware:注入ApplicationContext容器
- EmbeddedValueResolverAware:解析 ${}
- InitializingBean:初始化bean调用
自定义Bean对象实现BeanNameAware、ApplicationContextAware、InitializingBean接口。
public class Bean01 implements BeanNameAware, ApplicationContextAware, InitializingBean {
@Override
public void setBeanName(String name) {
System.out.println("Bean01 name is " + name);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("当前容器是: " + applicationContext);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("当前bean初始化: " + this);
}
}
public class A06Application {
public static void main(String[] args) {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("myBean01", Bean01.class);
context.refresh();
context.close();
}
}
Bean01 name is myBean01
当前容器是: org.springframework.context.support.GenericApplicationContext@19e1023e, started on Sat Oct 29 14:30:40 CST 2022
当前bean初始化: com.shuttle.spring5.Bean01@148080bb
为什么有了@Autowired等注解还需要Aware接口呢?
简单的说:
- @Autowired的解析需要用到Bean后处理器,属于扩展功能
- Aware接口属于内置功能,不需要添加任何扩展Spring就能识别
在某些情况下,扩展功能会失效,但内置功能不会。
@Configuration
public class MyConfig1 {
@Autowired
public void setApplicationContext(ApplicationContext applicationContext) {
System.out.println("@Autowired 注入ApplicationContext");
}
@PostConstruct
public void init() {
System.out.println("初始化...");
}
}
public static void main(String[] args) {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("myConfig1", MyConfig1.class);
context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
context.registerBean(CommonAnnotationBeanPostProcessor.class);
context.registerBean(ConfigurationClassPostProcessor.class);
context.refresh();
context.close();
}
运行上述程序结果如下:
@Autowired 注入ApplicationContext
初始化...
看起来还比较正常,一起来看看什么情况下注解会失效吧~
在配置类中添加如下代码:
@Bean
public BeanFactoryPostProcessor processor() {
return beanFactory -> {
System.out.println("execute processor...");
};
}
程序运行没有发现和@Autowired、@PostConstruct注解解析有关的信息。
为什么会出现上述情况呢?一起来看看【截取自满老师的课件】
简单来说,就是在配置类中注入BeanFactoryPostProcessor对象导致需要提前创建和初始化配置类,越过了注册BeanPostProcessor后处理器,进而导致@Autowired等注解解析不生效。
解决方案:使用内置接口
@Configuration
public class MyConfig2 implements ApplicationContextAware, InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("初始化...");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("当前容器是: " + applicationContext);
}
@Bean
public BeanFactoryPostProcessor processor() {
return beanFactory -> {
System.out.println("execute processor...");
};
}
}
注入MyConfig2对象后程序运行结果如下:
当前容器是: org.springframework.context.support.GenericApplicationContext@19e1023e, started on Sat Oct 29 14:53:44 CST 2022
初始化...execute processor...