Spring中最重要的功能就是帮助程序员创建对象(也就是IOC:对象交由Spring容器来管理),而启动Spring就是为创建Bean对象做准备,所以我们要弄明白Spring是怎么创建Bean对象的,也就是要弄明白Spring中Bean的生命周期。
Bean的生命周期是指:在Spring中Bean是如何创建的,如何销毁的。
Bean的生成过程
1.生成BeanDefinition
Spring在启动的过程中会先扫描,会先调用
public AnnotationConfigApplicationContext(String... basePackages) {this();scan(basePackages);refresh();}
通过调用链会调用
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {Set<BeanDefinition> candidates = new LinkedHashSet<>();try {// ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX值为classpath*:String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +resolveBasePackage(basePackage) + '/' + this.resourcePattern;// 拿到所指定的包路径下的所有文件资源(******.class文件)Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);boolean traceEnabled = logger.isTraceEnabled();boolean debugEnabled = logger.isDebugEnabled();for (Resource resource : resources) {if (traceEnabled) {logger.trace("Scanning " + resource);}if (resource.isReadable()) {try {MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);if (isCandidateComponent(metadataReader)) {ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);sbd.setSource(resource);if (isCandidateComponent(sbd)) {if (debugEnabled) {logger.debug("Identified candidate component class: " + resource);}candidates.add(sbd);}else {if (debugEnabled) {logger.debug("Ignored because not a concrete top-level class: " + resource);}}}else {if (traceEnabled) {logger.trace("Ignored because not matching any filter: " + resource);}}}catch (Throwable ex) {throw new BeanDefinitionStoreException("Failed to read candidate component class: " + resource, ex);}}else {if (traceEnabled) {logger.trace("Ignored because not readable: " + resource);}}}}catch (IOException ex) {throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);}return candidates;}
上面代码拿到所指定的包路径下的所有文件资源(**.class文件)
然后遍历Resource,为每个Resource生成一个MetadataReader对象,这个对象有三个功能:
public interface MetadataReader {
// 获取对应的resource资源
Resource getResource();
/**
* Read basic class metadata for the underlying class.
* 获取Resource对象的元数据信息,包括类的名字、是不是一个接口、是不是一个注解、是不是一个抽象类、
* 有没有父类、父类的名字,所实现所有接口的名字,内部类的名字等。
*/
ClassMetadata getClassMetadata();
/**
* Read full annotation metadata for the underlying class,
* including metadata for annotated methods.
* 获取Resource对应的class上的注解信息,当前类上有哪些注解,当前类上哪些方法上有注解
*/
AnnotationMetadata getAnnotationMetadata();
}
- 获取对应的resource资源
获取Resource对象的元数据信息,包括类的名字、是不是一个接口、是不是一个注解、是不是一个抽象类、
有没有父类、父类的名字,所实现所有接口的名字,内部类的名字等。获取Resource对应的class上的注解信息,当前类上有哪些注解,当前类上哪些方法上有注解
在生成MetadataReader对象时,会利用ASM技术解析class文件,得到类的元数据信息和注解信息,在这个过程中也会利用ClassLoader去加载注解类(ClassUtils.getDefaultClassLoader()所获得的类加载器),但是不会加载本类。
有了MetadataReader对象,相当于有了当前类的所有信息,但是当前类并没有加载,只有真正用到这个类的时候才会去被加载。
然后利用MetadataReader对象生成一个ScannedGenericBeanDefinition对象,注意此时的BeanDefinition对象中的beanClass属性存储的是当前类的名字,而不是class对象。
2.合并BeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
return mbd;
}
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
如果某个BeanDefinition存在父BeanDefinition,那么则要进行合并。
将继承父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<Class<?>>) () ->
doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
}else {
return doResolveBeanClass(mbd, typesToMatch);
}
public boolean hasBeanClass() {
return (this.beanClass instanceof Class);
}
如果beanClass属性类型为Class则直接返回,如果不是则会根据类名直接加载。
然后将得到的class设置为当前BeanDefinition的属性
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
4.实例化前
允许第三方可以不按照Spring的正常流程来创建一个Bean,可以利用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法来提前返回一个Bean对象,直接结束Bean的生命周期。
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// beforeInstantiationResolved为null或true
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 实例化前
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
5.推断构造方法
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 从ctors中自动选择一个构造方法
return autowireConstructor(beanName, mbd, ctors, args);
}
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
// 用无参的构造方法来实例化bean
return instantiateBean(beanName, mbd);
- 一个类有多个构造方法,那么到底哪些构造方法是可以拿来用的,Spring也提供了一个扩展点,程序员可以进行控制
- 利用beanPostProcessor来选取构造方法,如果返回值(ctors)不为空,则表示利用beanPostProcessor找到了候选的构造方法,那么则进行自动推断
- 如果当前bd是构造方法自动注入,那么也进行自动推断
- 如果当前bd中存在了构造方法参数值,那么也进行自动推断
- 如果是在getBean时指定了args, 那么也进行自动推断
6.实例化
构造方法反射得到一个对象
ReflectionUtils.makeAccessible(ctor);
if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
return KotlinDelegate.instantiateClass(ctor, args);
}else {
Class<?>[] parameterTypes = ctor.getParameterTypes();
Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
Object[] argsWithDefaultValues = new Object[args.length];
for (int i = 0 ; i < args.length; i++) {
if (args[i] == null) {
Class<?> parameterType = parameterTypes[i];
argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
}else {
argsWithDefaultValues[i] = args[i];
}
}
// 构造方法反射得到一个对象
return ctor.newInstance(argsWithDefaultValues);
}
7.BeanDefinition的后置处理器
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
这里可以处理BeanDefinition,但是此时实例对象已经生成好了,所以修改beanClass已经没用了,但是可以修改PropertyValues,比如:
@Component
public class TestMergedBeanDefinitionPostProcessor 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");
}
}
}
8.属性填充
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 此时的bean还没有完成属性注入,是一个非常简单的对象
// 构造一个对象工厂添加到singletonFactories中
// 第四次调用后置处理器
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
如果当前创建的Bean是单例的,并且允许循环依赖(默认为ture),并且这个bean这种被创建,则提前暴露
// 3、填充属性
populateBean(beanName, mbd, instanceWrapper);
9.执行Aware
invokeAwareMethods(beanName, 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);
}
}
10.初始化前
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
如果某个类实现了BeanPostProcessor并重写postProcessBeforeInitialization方法,将会处理里面的逻辑
11.初始化
invokeInitMethods(beanName, wrappedBean, mbd);
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// init-method=""
invokeCustomInitMethod(beanName, bean, mbd);
}
}
- 如果这个Bean实现了InitializingBean接口,将会调用afterPropertiesSet方法执行里面的逻辑;
- 执行BeanDefinition中指定的初始化方法
12.初始化后
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
如果某个类实现了BeanPostProcessor并重写postProcessAfterInitialization方法,将会处理里面的逻辑
