继续接着上一篇完成后续接口的解析
还是借用上一篇引用大佬的文章:https://www.jianshu.com/p/1dec08d290c1
第二篇spring Bean 生命周期及BeanPostProcessor和InstantiationAwareBeanPostProcessor详解
第二大类:只调用一次的接口(只做用于bean)
这一大类接口的特点是功能丰富,常用于用户自定义扩展。
第二大类中又可以分为两类:
- Aware类型的接口
- 生命周期接口
无所不知的Aware
Aware类型的接口的作用就是让我们能够拿到Spring容器中的一些资源。基本都能够见名知意,Aware之前的名字就是可以拿到什么资源,例如BeanNameAware
可以拿到BeanName,以此类推。调用时机需要注意:所有的Aware方法都是在初始化阶段之前调用的!
Aware接口众多,这里同样通过分类的方式帮助大家记忆。
Aware接口具体可以分为两组,至于为什么这么分,详见下面的源码分析。如下排列顺序同样也是Aware接口的执行顺序,能够见名知意的接口不再解释。
Aware Group1
- BeanNameAware
- BeanClassLoaderAware
- BeanFactoryAware
Aware Group2
- EnvironmentAware
- EmbeddedValueResolverAware 这个知道的人可能不多,实现该接口能够获取Spring EL解析器,用户的自定义注解需要支持spel表达式的时候可以使用,非常方便。
- ApplicationContextAware(ResourceLoaderAware\ApplicationEventPublisherAware\MessageSourceAware) 这几个接口可能让人有点懵,实际上这几个接口可以一起记,其返回值实质上都是当前的ApplicationContext对象,因为ApplicationContext是一个复合接口
作者:sunshujie1990
链接:https://www.jianshu.com/p/1dec08d290c1
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
我们还是从两个点来分析:
一是何时加入到beanFactory
二是何时调用
先从何时调用开始说明
准备测试代码:按上一节的测试代码测试(spring Bean 生命周期及BeanPostProcessor和InstantiationAwareBeanPostProcessor详解)
UserService实现下面的接口重写它们的方法
- BeanNameAware
- BeanClassLoaderAware
- BeanFactoryAware
@Component
public class UserService implements InitializingBean, BeanNameAware, BeanClassLoaderAware, BeanFactoryAware {
@Autowired
private Test test;
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean.afterPropertiesSet()-------------");
}
public void test() {
System.out.println("test");
}
@Override
public void setBeanName(String name) {
System.out.println(name);
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println(classLoader);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println(beanFactory);
}
}
还是debug调试,打上各接口重写方法的断点
找到方法的调用点:
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
由此可以知道是在invokeAwareMethods方法里面执行,观看源码可以很快的得知这三个Aware的执行顺序依次排序:
- BeanNameAware
- BeanClassLoaderAware
- BeanFactoryAware
从第一张图片也可看出跟上一节的BeanPostProcessor执行位置一样都是在
setBeanName:30, UserService (com.luban.service)
invokeAwareMethods:1925, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
initializeBean:1896, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:623, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:528, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:341, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, 1627821297 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$28)
getSingleton:243, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:339, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:204, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:917, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:918, AbstractApplicationContext (org.springframework.context.support)
refresh:574, AbstractApplicationContext (org.springframework.context.support)
<init>:107, AnnotationConfigApplicationContext (org.springframework.context.annotation)
main:10, Test (com.luban)
doCreateBean()方法里面(下一节写doCreateBean的源码)
其实就是在初始化new AnnotationConfigApplicationContext(AppConfig.class)时候会去实例化非懒加载的单例bean,在doCreateBean()方法里面有流程规定哪个时候调用上述接口的方法做一些个性化操作。
我这里也实现了InitializingBean方法,继续往下走断点可以看到InitializingBean的方法是执行在上面三个Aware方法之后
再看第二组的Aware
同理UserService实现这个几个接口,打上断点
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
从上面可以看出也是跟第一组Aware一样,只是先执行完在执行后面的,也是在初始化前。
查看控制台打印日志:
由打印日志可以知道生命周期的执行顺序:
1.InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
2.InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(Object bean, String beanName)
3.InstantiationAwareBeanPostProcessor.postProcessProperties(PropertyValues pvs, Object bean, String beanName):这里必须上面方法返回true才会执行
4.BeanNameAware.setBeanName(String name);
5.BeanClassLoaderAware.setBeanClassLoader(ClassLoader classLoader);
6.BeanFactoryAware.setBeanFactory(BeanFactory beanFactory)
7.EnvironmentAware.setEnvironment(Environment environment);
8.EmbeddedValueResolverAware.setEmbeddedValueResolver(StringValueResolver resolver);
9.ApplicationContextAware.setApplicationContext(ApplicationContext applicationContext)
10.BeanPostProcessor.postProcessBeforeInitialization(Object bean, String beanName)
11.InitializingBean.afterPropertiesSet()
12.BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName)
13.DisposableBean.destroy()
何时加入到beanFactory
其实何时加入到beanFactory里面,因为Aware是作用到单个bean上面,在实例化非懒加载单例bean的时候调用的,所以何时加入到beanFactory在第一篇已经说了(https://blog.csdn.net/weixin_42955916/article/details/117782347)这里就不说明了
下一节我们来看doCreateBean()方法源码
导航:
1.Spring Bean是怎么被创建进入工厂的
2.spring Bean 生命周期及BeanPostProcessor和InstantiationAwareBeanPostProcessor详解