什么是Bean的生命周期
Bean的生命周期就是指: 在Spring中,一个Bean是如何生成的,如何销毁的
Bean的生命周期:
Spring期启动的时候会进行包扫描,会先调用
ClassPathScanningCandidateComponentProvider#scanCandidateComponents(String basePackage)
去扫描某个包路径,并且将需要的class文件解析成BeanDefinition然后放到一个set集合中.
Spring包扫描底层流程:
// 获取basePackage下所有的文件资源
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
// Class文件的File对象
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
for (Resource resource : resources) {
...
}
// 从class文件中获取类元数据信息,比如注解信息,接口信息等,底层采用了ASM技术,这里就相当于这个类的代表
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
MetadataReader表示类的元数据读取器,主要包含一个AnnotationMetadata,功能有:
注意:
CachingMetadataReaderFactory解析某个.class文件得到MetadataReader对象是利用了ASM,并没有加载这个类到JVM内存中去,并且最终得到的ScannedGenericBeanDefinition对象,beanClass属性存储的是当前类的名字,而不是class对象.(beanClass属性的类型是Object,它既可以存储类的名字,也可以存储class对象)除了可以通过扫描得到BeanDefinition对象,我们还可以直接通过bean标签的形式去定义或者@Bean注解
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
implements BeanDefinition, Cloneable {
...
/**
* 为什么这里是Object,而不是Class>
* 因为这里还没有加载,只是通过ASM技术去解析了这个类,并没有去解析,只是把这个类的名字设置给了BeanDefinition的属性,当创建这个Bean的时候,才会去真正加载
*/
@Nullable
private volatile Object beanClass;
}
通过扫描得到的所有BeanDefinition之后,就可以根据BeanDefinition创建Bean对象了,但是在Spring中支持父子BeanDefintion,和Java父子类类似,但是不是一回事.
如如下情况,child无疑是单例bean
但是如下情况,child继承了parent的属性,成为了原型bean
而在根据child来生成Bean对象之前,需要进行BeanDefinition的合并,得到完整的child的BeanDefinition
(Spring源码中合并后的BeanDefinition是RootBeanDefinition,对应的合并逻辑在AbstractBeanFactory#getMergedBeanDefinition)
BeanDefinition合并之后,就可以去创建Bean对象了,而创建Bean就必须实例化对象,而实例化对象就必须先去加载当前BeanDefinition所对应的class,在
AbstractAutowireCapableBeanFactory#createBean方法中一开始会调用resolveBeanClass(mbd, beanName) 去进行判断
如果beanClass属性的类型是Class,那么就直接返回,否则,就会根据类名进行加载
后续就是通过AbstractBeanFactory#doResolveBeanClass去进行加载了,其中会利用BeanFactory所设置的类加载器来加载类
如果没有设置,就默认使用AbstractBeanFactory#
ClassUtils.getDefaultClassLoader() 所返回的类加载器去加载类
// 如果beanClass被加载了,就直接返回,加载了的话存的是Class
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
// 如果beanClass没有被加载
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);
}
public ClassLoader getBeanClassLoader() {
return this.beanClassLoader;
}
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
@Nullable
public static ClassLoader getDefaultClassLoader() {
ClassLoader cl = null;
// 优先获取线程中的类加载器
try {
cl = Thread.currentThread().getContextClassLoader();
}
catch (Throwable ex) {
// Cannot access thread context ClassLoader - falling back...
}
// 线程中类加载器为null的情况下,获取加载ClassUtils类的类加载器
if (cl == null) {
// No thread context class loader -> use class loader of this class.
// 默认使用AppClassLoader
cl = ClassUtils.class.getClassLoader();
if (cl == null) {
// getClassLoader() returning null indicates the bootstrap ClassLoader
// 加入ClassUtils是被Bootstrap类加载器加载的,则获取系统类加载器
try {
cl = ClassLoader.getSystemClassLoader();
}
catch (Throwable ex) {
// Cannot access system ClassLoader - oh well, maybe the caller can live with null...
}
}
}
return cl;
}