距离上一次写Spring源码解析,已通过去了快要好几个月了,主要缘由仍是Spring的源码解析类文章太难写了,不像我先前写的什么CAS源码,AQS源码,LinkedBlockingQueue等等,这些无非就是分析几个核心方法,代码也不算太长,就像比较复杂的AQS源码也是两篇搞定的,虽然AQS源码也不少东西也不能算是百分百的理解,可是核心思想应该是还算理解的。解析完毕成就感也满满的,写完博客,看着大段大段的文字,内心也很开心:哈哈哈,原来JDK源码也是能够读懂的,并且还能写出来。可是Spring源码就不同了,若是和先前的源码分析类文章同样逐行去解析的话,那么可能一篇博客写下来,一个小小小小小方法都无法分析完,就算分析完毕了,也突出不了重点啊,可是Spring源码解析仍是要继续的,就当作是本身的学习笔记把。html
今天咱们要看的内容是Spring Bean的生命周期,固然本篇博客只是带着你们俯瞰下,不会进行过多的源码分析,甚至只是贴下代码,不作分析,只是找到Spring Bean生命周期的回调或者钩子,固然这可能只是个人我的理解,你们仍是要以怀疑的目光看待,也许我分析的是有问题的。面试
不知道Spring官方对Bean的生命问题是否有明确的定义或者解析,可是Spring In Action以及市面上流传的大部分博客是这样的:spring
为了验证上面的逻辑,能够作个试验:app
首先定义了一个Bean,里面有各类回调和钩子,其中须要注意下,我在SpringBean的构造方法中打印了studentService,看SpringBean被new的出来的时候,studentService是否被注入了;又在setBeanName中打印了studentService,看此时studentService是否被注入了,以此来验证,Bean是什么时候完成的自动注入的(这个StudentServiceImpl 类的代码就不贴出来了,无非就是一个最普通的Bean):ide
public class SpringBean implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware, BeanClassLoaderAware { public SpringBean() { System.out.println("SpringBean构造方法:" + studentService); System.out.println("SpringBean构造方法"); } @Autowired StudentServiceImpl studentService; @Override public void afterPropertiesSet() throws Exception { System.out.println("afterPropertiesSet"); } @Override public void destroy() throws Exception { System.out.println("destroy"); } @Override public void setBeanClassLoader(ClassLoader classLoader) { System.out.println("setBeanClassLoader"); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("setBeanFactory"); } @Override public void setBeanName(String name) { System.out.println("setBeanName:" + studentService); System.out.println("setBeanName"); } public void initMethod() { System.out.println("initMethod"); } public void destroyMethod() { System.out.println("destroyMethod"); } }
再定义一个BeanPostProcessor,在重写的两个方法中进行了判断,若是传进来的beanName是springBean才进行打印:函数
@Component public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if(beanName.equals("springBean")) { System.out.println("postProcessBeforeInitialization"); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if(beanName.equals("springBean")) { System.out.println("postProcessAfterInitialization"); } return bean; } }
定义一个配置类,完成自动扫描,可是SpringBean是手动注册的,而且声明了initMethod和destroyMethod:源码分析
@Configuration @ComponentScan public class AppConfig { @Bean(initMethod = "initMethod",destroyMethod = "destroyMethod") public SpringBean springBean() { return new SpringBean(); } }
最后就是启动类了:post
public static void main(String[] args) { AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AppConfig.class); annotationConfigApplicationContext.destroy(); }
运行结果:学习
SpringBean构造方法:null SpringBean构造方法 setBeanName:com.codebear.StudentServiceImpl@31190526 setBeanName setBeanClassLoader setBeanFactory postProcessBeforeInitialization afterPropertiesSet initMethod postProcessAfterInitialization destroy destroyMethod
能够看到,试验结果和上面分析的彻底一致。this
这就是广为流传的Spring生命周期。
也许你在应付面试的时候,是死记硬背这些结论的,如今我带着你找到这些方法,跟我来。
首先咱们来到AnnotationConfigApplicationContext的构造方法:
//根据参数类型能够知道,其实能够传入多个annotatedClasses,可是这种状况出现的比较少 public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { //调用无参构造函数,会先调用父类GenericApplicationContext的构造函数 //父类的构造函数里面就是初始化DefaultListableBeanFactory,而且赋值给beanFactory //本类的构造函数里面,初始化了一个读取器:AnnotatedBeanDefinitionReader read,一个扫描器ClassPathBeanDefinitionScanner scanner //scanner的用处不是很大,它仅仅是在咱们外部手动调用 .scan 等方法才有用,常规方式是不会用到scanner对象的 this(); //把传入的类进行注册,这里有两个状况, //传入传统的配置类 //传入bean(虽然通常没有人会这么作 //看到后面会知道spring把传统的带上@Configuration的配置类称之为FULL配置类,不带@Configuration的称之为Lite配置类 //可是咱们这里先把带上@Configuration的配置类称之为传统配置类,不带的称之为普通bean register(annotatedClasses); //刷新 refresh(); }
进入refresh方法,refresh方法中有一个finishBeanFactoryInitialization小方法,这个方法是用来实例化懒加载单例Bean的,也就是咱们的Bean都是在这里被建立出来的(固然我这里说的的是绝大部分状况是这样的):
finishBeanFactoryInitialization(beanFactory);
咱们再进入finishBeanFactoryInitialization这方法,里面有一个beanFactory.preInstantiateSingletons()方法:
//初始化全部的非懒加载单例 beanFactory.preInstantiateSingletons();
咱们尝试再点进去,这个时候你会发现这是一个接口,好在它只有一个实现类,因此能够咱们来到了他的惟一实现,实现类就是org.springframework.beans.factory.support.DefaultListableBeanFactory,这里面是一个循环,咱们的Bean就是循环被建立出来的,咱们找到其中的getBean方法:
getBean(beanName);
这里有一个分支,若是Bean是FactoryBean,如何如何,若是Bean不是FactoryBean如何如何,好在不论是不是FactoryBean,最终仍是会调用getBean方法,因此咱们能够坚决果断的点进去,点进去以后,你会发现,这是一个门面方法,直接调用了doGetBean方法:
return doGetBean(name, null, null, false);
再进去,不断的深刻,接近咱们要寻找的东西。 这里面的比较复杂,可是有我在,我能够直接告诉你,下一步咱们要进入哪里,咱们要进入
if (mbd.isSingleton()) { //getSingleton中的第二个参数类型是ObjectFactory<?>,是一个函数式接口,不会马上执行,而是在 //getSingleton方法中,调用ObjectFactory的getObject,才会执行createBean sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }
这里面的createBean方法,再点进去啊,可是又点不进去了,这是接口啊,可是别慌,这个接口又只有一个实现类,因此说 没事,就是干,这个实现类为org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory。
这个实现的方法里面又作了不少事情,咱们就不去看了,我就是带着你们找到那几个生命周期的回调到底定义在哪里就OK了。
Object beanInstance = doCreateBean(beanName, mbdToUse, args);//建立bean,核心 if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance;
再继续深刻doCreateBean方法,这个方法又作了一堆一堆的事情,可是值得开心的事情就是 咱们已经找到了咱们要寻找的东西了。
首先是建立实例,位于:
instanceWrapper = createBeanInstance(beanName, mbd, args);//建立bean的实例。核心
其次是填充属性,位于:
populateBean(beanName, mbd, instanceWrapper);//填充属性,炒鸡重要
在填充属性下面有一行代码:
exposedObject = initializeBean(beanName, exposedObject, mbd);
继续深刻进去。
aware系列接口的回调位于initializeBean中的invokeAwareMethods方法:
invokeAwareMethods(beanName, bean);
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); } } }
BeanPostProcessor的postProcessBeforeInitialization方法位于initializeBean的
if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); }
@Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
afterPropertiesSet init-method位于initializeBean中的
invokeInitMethods(beanName, wrappedBean, mbd);
这里面调用了两个方法,一个是afterPropertiesSet方法,一个是init-method方法:
((InitializingBean) bean).afterPropertiesSet();
invokeCustomInitMethod(beanName, bean, mbd);
BeanPostProcessor的postProcessAfterInitialization方法位于initializeBean的
if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); }
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
固然在实际的开发中,应该没人会去销毁Spring的应用上下文把,因此剩余的两个销毁的回调就不去找了。
这就是广为流传的Spring Bean的生命周期,我也带着你们找到了各类回调和钩子,可是我认为这并不是是Spring Bean完整的生命周期,只是通过简化的,那么我认为的完整的生命周期是如何的呢,请听下回分解。
原文出处:https://www.cnblogs.com/CodeBear/p/10867707.html