目录
AutowiredAnnotationBeanPostProcessor运行分析
Bean的后处理器
AutowiredAnnotationBeanPostProcessor运行分析
里边装配主要方法是
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 获取bean上加相应注解的信息
InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 进行依赖注入
metadata.inject(bean, beanName, pvs);
return pvs;
} catch (BeanCreationException var6) {
throw var6;
} catch (Throwable var7) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", var7);
}
}
inject方法主要流程
- 拿到属性
- 封装成DependencyDescriptor
- 调用beanfactory的doResolveDependency方法
BeanFactory的后置处理器
ConfigurationClassPostProcessor:处理@ComponentScan 、@Bean、 @Import()、@ImportResource等注解
@ComponentScan
- 找到注解
- 找需要扫描的包,转化为classpath*:com/***(例子)的格式
- 拿到这些class文件
- 读取类的元数据
- 用类的元信息判断看是否有@Component注解包括合成注解如@Controller
- 含有则变为BeanDefinition,然后放入beanFactory
@Bean
处理@Bean和上边类似,但是在装配的时候如果有参数,则还需要指定注入模式。同时也可以获取到属性做需要的操作,比如在设置初始化方法等等。
@ComponentScan
新增判断是否是接口,需要新增加入sqlsessionfactory,在生成名字时,源码中的做法是又生成了一个beandefinition。
Aware
这个接口用于注入一些与容器有关的信息,比如
- BeanNameAware:注入bean的名字
-
BeanFactoryAware:注入BeanFactory容器
-
ApplicationContextAware:注入ApplicationContextAware容器
-
EmbeddedValueResolverAware:解析${}
InitializingBean
为Bean添加初始化方法
先调用aware接口,再触发初始化方法
问题
Q:Aware的某些功能用@Autowired就可以实现,为什么还要用到Aware的接口?
A:@Autowired需要用到bean的后处理器,是扩展功能。但是Aware属于内置功能,某些情况下@Autowired不能被识别,但是内置功能不会失效。比如未注册beanFactory后处理器。
案例1:
未注册beanFactory后处理器
public class MyMain {
public static void main(String[] args) {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("myConfig",MyConfig.class);
//注释掉添加后处理器
// context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
// context.registerBean(CommonAnnotationBeanPostProcessor.class);
context.refresh();
context.close();
}
}
public class MyConfig implements BeanNameAware, ApplicationContextAware, InitializingBean {
@Override
public void setBeanName(String s) {
System.out.println("name-------------------->"+s);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean初始化返回方法");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("ApplicationContextAware:applicationContext-------------------->"+applicationContext);
}
@Autowired
public void aaa(ApplicationContext applicationContext){
System.out.println("@Autowired:applicationContext-------------------->"+applicationContext);
}
@PostConstruct
public void init(){
System.out.println("@PostConstruct初始化返回方法");
}
}
如果不添加后置处理器,则@Autowired、@PostConstruct等bean后处理器处理的无法生效。打印结果为
name-------------------->myConfig
ApplicationContextAware:applicationContext-------------------->org.springframework.context.support.GenericApplicationContext@3f102e87, started on Tue May 24 14:07:12 CST 2022
InitializingBean初始化返回方法
如果主启动类注释放开(加上后处理器),结果为
@Autowired:applicationContext-------------------->org.springframework.context.support.GenericApplicationContext@3f102e87, started on Tue May 24 14:08:46 CST 2022
name-------------------->myConfig
ApplicationContextAware:applicationContext-------------------->org.springframework.context.support.GenericApplicationContext@3f102e87, started on Tue May 24 14:08:46 CST 2022
@PostConstruct初始化返回方法
InitializingBean初始化返回方法
案例2:
Java配置类包含了BeanFactoryPostProcessor
public class MyMain {
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();
}
}
@Configuration
public class MyConfig1{
@Autowired
public void aaa(ApplicationContext applicationContext){
System.out.println("@Autowired:applicationContext-------------------->"+applicationContext);
}
@PostConstruct
public void init(){
System.out.println("@PostConstruct初始化返回方法");
}
// @Bean
// public BeanFactoryPostProcessor processor1(){
// return configurableListableBeanFactory -> System.out.println("processor1执行");
// }
}
结果正常为
@Autowired:applicationContext-------------------->org.springframework.context.support.GenericApplicationContext@3f102e87, started on Tue May 24 14:17:12 CST 2022
@PostConstruct初始化返回方法
当我们把MyConfig1注释放开,加一个BeanFactoryPostProcessor的bean时,打印结果为
processor1执行
我们发现@Autowired和@PostConstruct并没有执行。为什么?
我们先来了解一下refresh()的大概步骤
- beanFactory后处理器注册beanDefinition
- 注册bean后处理器
- 初始化单例
- 依赖注入扩展@Autowired
- 初始化扩展@PostConstruct
- 执行Aware和InitializingBean
- 创建成功
但是,我们的Java配置类包含了BeanFactoryPostProcessor所以要创建beanFactory后处理器要先创建Java配置类,但是这个时候bean后处理器还没准备好,所以@Autowired和@PostConstruct等注解失效。顺序变为
- 创建和初始化
- 执行Aware和InitializingBean
- 创建成功
- beanFactory后处理器注册beanDefinition
- 注册bean后处理器
解决办法,改为实现Aware和InitializingBean接口。代码不再赘述。
初始化
三种方法:
- @PostConstruct
- InitializingBean
- @Bean(initMethod = "name")
执行顺序是@PostConstruct——>InitializingBean——>@Bean(initMethod = "name")
销毁
三种方法:
- @PreDestroy
- 实现DisposableBean
- @Bean(destroyMethod = "name")
也是先执行扩展功能,再执行内置功能,在执行@Bean