本文共 4618 字,大约阅读时间需要 15 分钟。
Spring最重要的功能就是帮助程序员创建对象(也就是IOC),而启动Spring就是为创建Bean对象做准备,所以我们先明白Spring到底是怎么去创建Bean的,也就是先弄明白Bean的生命周期。
Bean的生命周期就是指:在Spring中,一个Bean是如何生成的,如何销毁的?1. 生成BeanDefinition
Spring启动的时候会进行扫描,会先调用Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
拿到所指定的包路径下的所有文件资源(******.class文件)
然后会遍历每个Resource,为每个Resource生成一个MetadataReader对象,这个对象拥有三个功能:2. 合并BeanDefinition
如果某个BeanDefinition存在父BeanDefinition,那么则要进行合并3. 加载类
有了BeanDefinition之后,后续就会基于BeanDefinition去创建Bean,而创建Bean就必须实例化对象,而实例化就必须先加载当前BeanDefinition所对应的class,在AbstractAutowireCapableBeanFactory类的createBean()方法中,一开始就会调用:Class resolvedClass = resolveBeanClass(mbd, beanName);
这行代码就是去加载类,该方法是这么实现的:
if (mbd.hasBeanClass()) { return mbd.getBeanClass();}if (System.getSecurityManager() != null) { return AccessController.doPrivileged((PrivilegedExceptionAction>) () -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext()); }else { return doResolveBeanClass(mbd, typesToMatch);}public boolean hasBeanClass() { return (this.beanClass instanceof Class);}
1.如果beanClass属性的类型是Class,那么就直接返回,如果不是,则会根据类名进行加载(doResolveBeanClass方法所做的事情)
会利用BeanFactory所设置的类加载器来加载类,如果没有设置,则默认使用ClassUtils.getDefaultClassLoader()所返回的类加载器来加载。 ClassUtils.getDefaultClassLoader()优先获取当前线程中的ClassLoader
2. 如果为空,则获取加载ClassUtils类的类加载器(正常情况下,就是AppClassLoader,但是如果是在Tomcat中运行,那么则会是Tomcat中为每个应用所创建的WebappClassLoader) 3. 如果为空,那么则是bootstrap类加载器加载的ClassUtils类,那则获取系统类加载器进行加载 3. 实例化前 允许第三方可以不按照Spring的正常流程来创建一个Bean,可以利用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法来提前返回一个Bean对象,直接结束Bean的生命周期 4. 推断构造方法 5. 实例化 构造方法反射得到一个实例 6. BeanDefinition的后置处理for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof MergedBeanDefinitionPostProcessor) { MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp; bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName); }}
这里可以处理BeanDefinition,但是此时实例对象已经生成好了,所以修改beanClass已经没用了,但是可以修改PropertyValues,比如:
@Componentpublic class LubanMergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor { @Override public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName) { if (beanName.equals("userService")) { beanDefinition.setBeanClass(User.class); // 没用 beanDefinition.getPropertyValues().add("name","xxx"); } }}
7. 填充属性
注解:autowired/resource xml配置:byName/byType/no 8. 执行Aware1. ((BeanNameAware) bean).setBeanName(beanName);2. ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);3. ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
9. 初始化前
for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current;}
10. 初始化
1. ((InitializingBean) bean).afterPropertiesSet();
for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current;}
Bean的销毁过程
这里涉及到一个设计模式:适配器模式
在销毁时,Spring会找出实现了DisposableBean接口的Bean。 但是我们在定义一个Bean时,如果这个Bean实现了DisposableBean接口,或者实现了AutoCloseable接口,或者在BeanDefinition中指定了destroyMethodName,那么这个Bean都属于“DisposableBean”,这些Bean在容器关闭时都要调用相应的销毁方法。 所以,这里就需要进行适配,将实现了DisposableBean接口、或者AutoCloseable接口等适配成实现了DisposableBean接口,所以就用到了DisposableBeanAdapter。 会把实现了AutoCloseable接口的类封装成DisposableBeanAdapter,而DisposableBeanAdapter实现了DisposableBean接口。转载地址:http://sikgn.baihongyu.com/