飞道的博客

Spring系列 之 带你走进源码

238人阅读  评论(0)

参考文档:

请别再问Spring Bean的生命周期了!

Spring开闭原则的表现-BeanPostProcessor的扩展点-1

Spring使用xml启动源码解析

Spring系列之Bean的生命周期及相关源码

通过AnnotationConfigApplicationContext类,采用注解配置bean的方式,简单解读Spring源码.

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
   
	this();
	register(componentClasses);
	refresh();
}

一. 创建BeanFactory

AnnotationConfigApplicationContext继承自父类GenericApplicationContext

private final DefaultListableBeanFactory beanFactory;
...
/**
* Create a new GenericApplicationContext.
 * @see #registerBeanDefinition
 * @see #refresh
 */
public GenericApplicationContext() {
   
	this.beanFactory = new DefaultListableBeanFactory();
}

父类构造方法中,BeanFactory被实例化

二. 创建一个BeanDefinition读取器,用于添加BeanFactory 后置处理器以及Bean后置处理器

方法入口在AnnotationConfigApplicationContext无参构造方法,即this()

public AnnotationConfigApplicationContext() {
   
	StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
	this.reader = new AnnotatedBeanDefinitionReader(this);
	createAnnotatedBeanDefReader.end();
	this.scanner = new ClassPathBeanDefinitionScanner(this);
}

主要代码
org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors

...

Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
   
	RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
	def.setSource(source);
	beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}

if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
   
	RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
	def.setSource(source);
	beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}

// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
   
	RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
	def.setSource(source);
	beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
...

ConfigurationClassPostProcessor会解析加了@Configuration的配置类,加了@Bean注解的类,还会解析@ComponentScan@ComponentScans注解扫描的包,以及解析@Import等注解。

AutowiredAnnotationBeanPostProcessor会解析加了@Autowired的类、@Value的参数。

CommonAnnotationBeanPostProcessor会解析加了@PostConstruct@PreDestroy标注的方法,以及@Resource标记的字段或方法。

三. 将上述Bean解析并注册到Spring上下文中

方法入口为register(componentClasses);

主要代码
org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean

...

// 完成条件注解@Conditional的解析和判断
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
   
	return;
}
...

// 处理类上的通用注解
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
...

// 把BeanDefination封装为BeanDefinitionHolder
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
// 根据scopedProxyMode为Bean创建相应模式的代理对象
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 注册到Spring容器中,即ApplicationContext中
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);

四. 容器刷新

refresh();
主要包括配置 BeanFactory、执行BeanFactory后置处理器、执行Bean实例化前的后置处理器、Bean的实例化、执行Bean实例化后的后置处理器、属性赋值、执行Bean初始化前的后置处理器、Bean初始化、执行Bean初始化后的后置处理器、Bean销毁。

4.1 配置BeanFactory,添加一些内置组件,预处理过程

// 获取第一步创建的BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// 配置BeanFactory
prepareBeanFactory(beanFactory);

主要代码
org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory

...

//设置Spring el表达式实现 
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
...

// 添加bean后置处理器, 如果实现了相应的 Aware 接口,则注入对应的资源
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
...

// 注册可以解析的自动装配类,即可以在任意组件中通过注解自动注入
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
...

// 判断存在AOP beanName ,则添加编译时的 AspectJ
if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
   
	beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
	beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
...

4.2 执行BeanFactory后置处理器,将Bean添加到Spring容器中

用户自定义的,实现了BeanFactoryPostProcessor接口的后置处理器,就是在该步骤执行。
用户自定义的bean,也是在这一步被注册到Spring容器中。

// 执行 BeanFactoryPostProcessor 方法,beanFactory 后置处理器
invokeBeanFactoryPostProcessors(beanFactory);

主要代码
org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

代码就不列出来了,主要流程如下:

  1. 遍历循环所有BeanFactoryPostProcessor集合,首先取出BeanDefinitionRegistryPostProcessor,并且执行接口方法,再放入registryProcessors容器中。
  2. BeanFactory 中获取所有BeanDefinitionRegistryPostProcessor类型的beanName 数组,遍历循环数据,判断是否有PriorityOrdered接口,加入容器中,并且根据接口重新排序后,遍历容器所有类,执行接口方法,加入registryProcessors容器中。
  3. 重新获取所有BeanDefinitionRegistryPostProcessor类型的beanName 数组,循环遍历取出实现Ordered接口,按照Orderd顺序排序集合,依次执行接口方法,加入放入registryProcessors容器中.
  4. 将剩下所有BeanDefinitionRegistryPostProcessor,加入registryProcessors容器中。执行registryProcessors容器中所有BeanFactoryPostProcessor的接口方法。
  5. BeanFactoryPostProcessor也是按照上面的思路,先过滤排序执行接口方法。

采用注解方式,大部分bean都是通过ConfigurationClassPostProcessor后置处理器注册到Spring容器中的。

bean注册到Spring容器的主要方法:org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition

在Spring中,所有的bean被保存在容器的beanDefinitionMap中,类型是Map<String, BeanDefinition>.

4.3 Bean的实例化、属性赋值、初始化以及Bean后置处理器的执行

// 初始化所有非延迟加载 单例 bean 
finishBeanFactoryInitialization(beanFactory);

往里找,会找到如下方法:
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
Spring Bean的主要生命周期就在这个方法中

主要流程:

4.3.1 执行Bean实例化前的后置处理器

实例化前的后置处理器,在上述图中createBean方法中执行。

主要方法:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation

	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
   
		Object bean = null;
		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;
	}

BeanPostProcessor扩展点,可以通过实现InstantiationAwareBeanPostProcessor接口,通过重写postProcessBeforeInstantiation方法,返回自定义的对象或者代理对象。如果返回的bean不为空,会继续执行bean初始化后的后置处理器,Spring将不会执行bean属性的注入,以及bean的初始化。

4.3.2 Bean的实例化

Bean的实例化,在上述图中createBeanInstance方法中执行。

根据指定bean使用对应的策略创建新的实例,如:工厂方法、构造函数注入、简单初始化。

主要代码
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance

...

// 确保class不为空,并且访问权限为public
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
   
	throw new BeanCreationException(mbd.getResourceDescription(), beanName,
			"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}

// 通过回调方法创建对象,但是其后面的生命周期不影响。
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
   
	return obtainFromSupplier(instanceSupplier, beanName);
}
// 使用工厂方法初始化策略
if (mbd.getFactoryMethodName() != null) {
   
	return instantiateUsingFactoryMethod(beanName, mbd, args);
}

// 是否有构造函数或者工厂方法
boolean resolved = false;
// 构造器是否有参数
boolean autowireNecessary = false;
if (args == null) {
   
	synchronized (mbd.constructorArgumentLock) {
   
		// spring会将解析、确定好的构造函数缓存到RootBeanDefinition的resolvedConstructorOrFactoryMethod中
		// 在下次创建相同的bean时,直接从RootBeanDefiniton中的属性缓存中获取,避免重复解析
		if (mbd.resolvedConstructorOrFactoryMethod != null) {
   
			resolved = true;
			autowireNecessary = mbd.constructorArgumentsResolved;
		}
	}
}
if (resolved) {
   
	if (autowireNecessary) {
   
		// 使用有参构造函数创建
		return autowireConstructor(beanName, mbd, null, null);
	}
	else {
   
		// 使用默认构造函数创建
		return instantiateBean(beanName, mbd);
	}
}

// 寻找当前正在实例化的bean中有@Autowired注解的 构造函数
// 自动注入有三种模式:属性、构造方法、普通方法
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
/**
 * 以下情况符合其一即可使用有参构造函数创建
 * 1.存在可选构造方法
 * 2.自动装配模型为构造函数自动装配
 * 3.RootBeanDefinition中设置的有构造函数所需参数值
 * 4.参与构造函数的参数不为空
 */
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
		mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
   
	return autowireConstructor(beanName, mbd, ctors, args);
}

// 找到默认的构造方法
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
   
	return autowireConstructor(beanName, mbd, ctors, null);
}

// 使用默认的无参构造方法进行初始化
return instantiateBean(beanName, mbd);

4.3.3 执行bean实例化后的后置处理器

在上图populateBean方法中执行
主要代码
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
   
	for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
   
		if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
   
			return;
		}
	}
}

BeanPostProcessor扩展点,可以通过实现InstantiationAwareBeanPostProcessor接口,通过重写postProcessAfterInstantiation方法,完成对bean的属性赋值,返回false,不再通过Spring处理属性。

注意:如果返回falseBeanFactory后置处理器对bean属性的操作也会不生效!

4.3.4 属性赋值

在上图populateBean方法中执行
主要代码
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
   
	MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
	// 根据名称自动注入
	if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
   
		autowireByName(beanName, mbd, bw, newPvs);
	}
	// 根据类型自动注入
	if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
   
		autowireByType(beanName, mbd, bw, newPvs);
	}
	pvs = newPvs;
}

boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

PropertyDescriptor[] filteredPds = null;
// 执行实现InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues方法,对属性再进行处理
if (hasInstAwareBpps) {
   
	if (pvs == null) {
   
		pvs = mbd.getPropertyValues();
	}
	for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
   
		PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
		if (pvsToUse == null) {
   
			if (filteredPds == null) {
   
				filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			}
			pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
			if (pvsToUse == null) {
   
				return;
			}
		}
		pvs = pvsToUse;
	}
}
// 依赖检查
if (needsDepCheck) {
   
	if (filteredPds == null) {
   
		filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
	}
	checkDependencies(beanName, mbd, filteredPds, pvs);
}

if (pvs != null) {
   
	// 将属性值设置到Bean中
	applyPropertyValues(beanName, mbd, bw, pvs);
}

BeanPostProcessor扩展点,可以通过实现InstantiationAwareBeanPostProcessor接口,通过重写postProcessProperties方法,完成对bean的属性赋值。

@Autowired@Resource注解修饰的属性,都是在这一步被注入。

4.3.5 执行Bean初始化前的后置处理器

在上图initializeBean方法中执行
主要代码
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean

...

// 调用BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
// Aware类型的接口的作用就是让我们能够拿到Spring容器中的一些资源。
// Aware之前的名字就是可以拿到什么资源,例如Bean实现EnvironmentAware接口,可以拿到Environment,以此类推。
// 所有的Aware方法都是在初始化阶段之前调用的
invokeAwareMethods(beanName, bean);
...

Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
   
	// 执行BeanPostProcessor扩展点的postProcessBeforeInitialization进行修改实例化Bean  
	// 调用 EnvironmentAware、EmbeddedValueResolverAware、ApplicationContextAware
	wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

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;
}

BeanPostProcessor扩展点,实现BeanPostProcessor接口中的postProcessBeforeInitialization方法即可。

@PostConstruct注解修饰的方法,也是在该扩展点,通过CommonAnnotationBeanPostProcessor后置处理器执行。

4.3.6 Bean初始化

在上图initializeBean方法中执行
主要代码
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods

...

// 如果当前bean是 InitializingBean类型的
// 并且afterPropertiesSet这个方法没有注册为外部管理的初始化方法
// 回调afterPropertiesSet方法
((InitializingBean) bean).afterPropertiesSet();
...

// 如果设置了initMethod方法的话
// 并且这个类不是 InitializingBean类型
// 并且这个方法不是 afterPropertiesSet方法
// 执行用户配置的初始话方法
invokeCustomInitMethod(beanName, bean, mbd);
...

实现InitializingBean接口的类,其中的afterPropertiesSet()方法会在上述afterPropertiesSet()中执行。

@Bean(initMethod = "xxx")如果采用这种方式定义beaninitMethod方法,该类中的xxx()方法会在上述invokeCustomInitMethod方法中执行。

至此,bean的初始化完成。

4.3.7 执行Bean初始化后的后置处理器

在上图initializeBean方法中执行
主要代码
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean

wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

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;
}

BeanPostProcessor扩展点,实现BeanPostProcessor接口中的postProcessAfterInitialization方法即可。

如果一个bean被AOP代理,也是在本扩展点创建代理对象!

五、 Bean销毁

方法入口为
org.springframework.context.support.AbstractApplicationContext#close
通过实现DisposableBean接口的destroy方法,可以增加Bean销毁前的处理。

六、 测试

码云地址
有兴趣的朋友,可以在com.example.demo.DemoApplicationTests中运行代码,看看各个扩展点的执行顺序。

	@Test
    void contextLoads() {
   
        ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        IMyTest myTest = context.getBean("myTest", IMyTest.class);
        myTest.say();
        ((AnnotationConfigApplicationContext) context).close();
    }


转载:https://blog.csdn.net/a770794164/article/details/115863665
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场