乐趣区

关于java:源码解析Spring源码解析笔记四启动过程下

本文由 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 生命周期的所有过程,启动过程篇幅完结!

接下来的文章咱们会持续钻研这些接口相干的设计。

退出移动版