本文由 colodoo(纸伞)整顿
QQ 425343603
Java 学习交换群(717726984)以后 Spring 源码版本是 5.2.10.RELEASE
承接上一篇文章源码解析:Spring 源码解析笔记(三)启动过程(中)。
上一篇文章,咱们理解了咱们定义的 beanDefinition 是怎么被实例化的,但还不是齐全体,还不是咱们平时用到的 bean 对象,咱们持续浏览源码,看看 bean 是怎么 属性填充 并实现 初始化 的。
实现刷新(finishRefresh)
org.springframework.context.support.AbstractApplicationContext#finishRefresh
protected void finishRefresh() {// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// 为此上下文初始化生命周期处理器。initLifecycleProcessor();
// 获取生命周期
// 刷新生命周期
// 首先将刷新流传到生命周期处理器.
getLifecycleProcessor().onRefresh();
// 公布最终流动.
publishEvent(new ContextRefreshedEvent(this));
// 参加 LiveBeansView MBean(如果流动).
LiveBeansView.registerApplicationContext(this);
}
初始化生命周期处理器(initLifecycleProcessor)
org.springframework.context.support.AbstractApplicationContext#initLifecycleProcessor
protected void initLifecycleProcessor() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 获取生命周期处理器
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
// 获取到这设置到以后对象 lifecycleProcessor 中
this.lifecycleProcessor =
beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
if (logger.isTraceEnabled()) {logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
}
}
else {
// 初始化默认生命周期处理器
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
// 为生命周期处理器设置 bean 工厂对象
defaultProcessor.setBeanFactory(beanFactory);
// 设置生命周期处理器
this.lifecycleProcessor = defaultProcessor;
// 注册生命周期处理器到 bean 工厂中
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
if (logger.isTraceEnabled()) {
logger.trace("No'" + LIFECYCLE_PROCESSOR_BEAN_NAME + "'bean, using" +
"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
}
}
}
总结一下这段代码
- 获取容器中存在的生命周期处理器,存在则设置,不存在则初始化。
- 初始化默认生命周期处理器(DefaultLifecycleProcessor)
- 默认生命周期处理器(defaultProcessor)注册到 bean 工厂(beanFactory)中。
这一步顾名思义就是把咱们生命周期初始化须要用到的 lifecycleProcessor 筹备好,接下来就要真正进入 bean 生命周期了。
生命周期刷新(onRefresh)
org.springframework.context.support.DefaultLifecycleProcessor#onRefresh
public void onRefresh() {startBeans(true);
this.running = true;
}
进入到这个办法中发现具体实现逻辑在 startBeans 办法中,持续往下浏览。
启动 Beans(startBeans)
org.springframework.context.support.DefaultLifecycleProcessor#startBeans
private void startBeans(boolean autoStartupOnly) {
// 获取生命周期 Bean 对象(多个)Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
// 阶段
Map<Integer, LifecycleGroup> phases = new HashMap<>();
// 遍历所有生命周期对象
lifecycleBeans.forEach((beanName, bean) -> {
//
if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {int phase = getPhase(bean);
LifecycleGroup group = phases.get(phase);
if (group == null) {group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
phases.put(phase, group);
}
group.add(beanName, bean);
}
});
if (!phases.isEmpty()) {List<Integer> keys = new ArrayList<>(phases.keySet());
Collections.sort(keys);
for (Integer key : keys) {phases.get(key).start();}
}
}
总结下这部分代码:
- 获取生命周期 bean(getLifecycleBeans)
- 同时进行生命周期 bean 实例化(getLifecycleBeans)
咱们持续浏览 getLifecycleBeans 这个办法,看看有没有咱们想要的货色。
获取生命周期 Bean(getLifecycleBeans)
org.springframework.context.support.DefaultLifecycleProcessor#getLifecycleBeans
protected Map<String, Lifecycle> getLifecycleBeans() {
// 获取 bean 工厂对象
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 初始化 beans
Map<String, Lifecycle> beans = new LinkedHashMap<>();
// 获取所有生命周期对象
// 这里获取到的值是 lifecycleProcessor
String[] beanNames = beanFactory.getBeanNamesForType(Lifecycle.class, false, false);
for (String beanName : beanNames) {
// 获取用于注册的 bean 名称
// 默认状况输入 -> lifecycleProcessor
String beanNameToRegister = BeanFactoryUtils.transformedBeanName(beanName);
// 判断是否为工厂 bean
// 这里默认状况输入 -> false
boolean isFactoryBean = beanFactory.isFactoryBean(beanNameToRegister);
// 如果为工厂 bean 则首字母加一个“&”符号
// 这里不是工厂 bean 输入 -> lifecycleProcessor
String beanNameToCheck = (isFactoryBean ? BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
// 判断是否存在该对象
if ((beanFactory.containsSingleton(beanNameToRegister) &&
(!isFactoryBean || matchesBeanType(Lifecycle.class, beanNameToCheck, beanFactory))) ||
matchesBeanType(SmartLifecycle.class, beanNameToCheck, beanFactory)) {
// 对该对象进行实例化
Object bean = beanFactory.getBean(beanNameToCheck);
if (bean != this && bean instanceof Lifecycle) {beans.put(beanNameToRegister, (Lifecycle) bean);
}
}
}
// 返回实例化后的生命周期对象
return beans;
}
这一步很显著,后面都是对生命周期对象的 bean 名称进行获取。
看到咱们很相熟的beanFactory.getBean,阐明它又帮生命周期 bean 进行了实例化,最初返回实例化后的生命周期对象。
beanFactory.getBean 这部分的源码,能够浏览上一篇文章 源码解析:Spring 源码解析笔记(三)启动过程(中)
浏览到这里,咱们没有发现属性注入的中央,反过头来看看是不是晓得脱漏了哪些地方。
通过我的调试,发现须要革新一下咱们的代码,因为我发现咱们的代码并没有存在依赖关系,咱们的 userService 并没有依赖任何的其余 bean。
咱们新建一个 userController 去调用它,并且依赖 userService 这个 bean。
革新代码
UserController
package com.zhisan.spring.controller;
import com.zhisan.spring.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
public class UserController {
@Autowired
private UserService userService;
public void login() {userService.login();
}
public UserService getUserService() {return userService;}
public void setUserService(UserService userService) {this.userService = userService;}
}
MainXml.java
package com.zhisan.spring;
import com.zhisan.spring.config.Config;
import com.zhisan.spring.controller.UserController;
import com.zhisan.spring.service.UserService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainXml {public static void main(String[] args) {
// XML 形式
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
UserController userController = applicationContext.getBean("userController", UserController.class);
userController.login();}
}
spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:task="http://www.springframework.org/schema/task" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="userController" class="com.zhisan.spring.controller.UserController">
<property name="userService" ref="userService"></property>
</bean>
<bean id="userService" class="com.zhisan.spring.service.UserService"> </bean>
</beans>
革新完后,咱们持续调试。
在上面这 populateBean 办法上打上断点,不便调试。
因为寻找入口的过程比拟漫长,所以两头的篇幅就省略了。
填充 Bean(populateBean)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// 这里省略了一些无关的逻辑代码...
// 这里会把类中的属性值都获取到
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 省略一些校验代码...
// 判断属性值列表是否为空,不空则进入属性利用
if (pvs != null) {applyPropertyValues(beanName, mbd, bw, pvs);
}
}
这部分的代码次要是实现属性填充的一些获取和校验,真正的填充属性值逻辑在applyPropertyValues,咱们持续浏览这个办法。
利用属性值(applyPropertyValues)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyPropertyValues
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
// 判断是否为空
if (pvs.isEmpty()) {return;}
// 校验环境
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
// 变量筹备
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
// 判断类型
if (pvs instanceof MutablePropertyValues) {mpvs = (MutablePropertyValues) pvs;
// 判断是否曾经转换
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
// 获取属性值列表
// result = {ArrayList@1625} size = 1
// 0 = {PropertyValue@1990} "bean property'userService'"// name ="userService"// value = {RuntimeBeanReference@2000}"<userService>"
// optional = false
// converted = false
// convertedValue = null
// conversionNecessary = null
// resolvedTokens = null
// source = null
// attributes = {LinkedHashMap@2001} size = 0
original = mpvs.getPropertyValueList();}
else {original = Arrays.asList(pvs.getPropertyValues());
}
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {converter = bw;}
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original) {if (pv.isConverted()) {deepCopy.add(pv);
}
else {String propertyName = pv.getName();
Object originalValue = pv.getValue();
if (originalValue == AutowiredPropertyMarker.INSTANCE) {Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
if (writeMethod == null) {throw new IllegalArgumentException("Autowire marker for property without write method:" + pv);
}
originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
}
// 属性值实例化
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
if (resolvedValue == originalValue) {if (convertible) {pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {mpvs.setConverted();
}
// 两头没有中文正文的局部能够疏忽... 不是次要逻辑
try {
// 设置属性值
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
这部分做了如下几件事:
- 遍历了所有的属性值(for)
- 实例化属性值所需的 bean 并获取(resolveValueIfNecessary)
- 转换属性(convertForProperty)
- 填充属性(setPropertyValues)
设置属性(setValue)
org.springframework.beans.BeanWrapperImpl.BeanPropertyHandler#setValue
public void setValue(@Nullable Object value) throws Exception {
// 通过反射获取到 setter 办法的对象
// 这里输入:public void com.zhisan.spring.controller.UserController.setUserService(com.zhisan.spring.service.UserService)
Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :
this.pd.getWriteMethod());
// 设置可拜访
if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {ReflectionUtils.makeAccessible(writeMethod);
return null;
});
try {AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
() -> writeMethod.invoke(getWrappedInstance(), value), acc);
}
catch (PrivilegedActionException ex) {throw ex.getException();
}
}
else {
// 设置可拜访办法
ReflectionUtils.makeAccessible(writeMethod);
// 执行办法
// value=userService 对象
writeMethod.invoke(getWrappedInstance(), value);
}
}
这里是真正填充属性的逻辑办法,原理也是基于 反射。
- 通过反射获取到 setter 办法
- 通过执行 setter 办法把解决后的参数设置到属性中。
至此,实现是 填充属性 这个步骤,接下来就是要实现 bean 生命周期中的最初一步,实现 初始化。
初始化 Bean(initializeBean)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 调用 Aware 办法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
这里除了调用 invokeInitMethods 这个办法是次要逻辑,其余局部临时能够疏忽,持续浏览 invokeInitMethods 办法。
调用设置办法(invokeInitMethods)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 是否初始化 bean
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {if (logger.isTraceEnabled()) {logger.trace("Invoking afterPropertiesSet() on bean with name'" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {throw pae.getException();
}
}
else {((InitializingBean) bean).afterPropertiesSet();}
}
if (mbd != null && bean.getClass() != NullBean.class) {String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// 调用自定义初始化办法
// 判断该 bean 上是否含有初始化办法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
这个局部最次要的逻辑就是判断对象是否,须要执行初始化办法,具体逻辑在 invokeCustomInitMethod 这个办法中。
调用自定义初始化办法(invokeCustomInitMethod)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeCustomInitMethod
- 获取 bean 定义(beanDefinition)中的初始化办法。
- 通过反射获取初始化办法
- 执行初始化办法
这是这个办法的逻辑,就不具体解析源码了。
最初
至此,实现 bean 生命周期的所有过程,启动过程篇幅完结!
接下来的文章咱们会持续钻研这些接口相干的设计。