距离上一次写Spring源码解析,已通过去了快要好几个月了,主要缘由仍是Spring的源码解析类文章太难写了,不像我先前写的什么CAS源码,AQS源码,LinkedBlockingQueue等等,这些无非就是分析几个核心方法,代码也不算太长,就像比较复杂的AQS源码也是两篇搞定的,虽然AQS源码也不少东西也不能算是百分百的理解,可是核心思想应该是还算理解的。解析完毕成就感也满满的,写完博客,看着大段大段的文字,内心也很开心:哈哈哈,原来JDK源码也是能够读懂的,并且还能写出来。可是Spring源码就不同了,若是和先前的源码分析类文章同样逐行去解析的话,那么可能一篇博客写下来,一个小小小小小方法都无法分析完,就算分析完毕了,也突出不了重点啊,可是Spring源码解析仍是要继续的,就当作是本身的学习笔记把。面试
今天咱们要看的内容是Spring Bean的生命周期,固然本篇博客只是带着你们俯瞰下,不会进行过多的源码分析,甚至只是贴下代码,不作分析,只是找到Spring Bean生命周期的回调或者钩子,固然这可能只是个人我的理解,你们仍是要以怀疑的目光看待,也许我分析的是有问题的。spring
不知道Spring官方对Bean的生命问题是否有明确的定义或者解析,可是Spring In Action以及市面上流传的大部分博客是这样的:bash
为了验证上面的逻辑,能够作个试验: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
复制代码
能够看到,试验结果和上面分析的彻底一致。ui
这就是广为流传的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完整的生命周期,只是通过简化的,那么我认为的完整的生命周期是如何的呢,请听下回分解。