美文网首页
spring 源码分析(二)Core

spring 源码分析(二)Core

作者: sschrodinger | 来源:发表于2019-03-15 17:06 被阅读0次

spring 源码分析(二)Core

sschrodinger

2019/03/14


参考


Spring 中 Bean 的生命周期是怎样的?-
大闲人柴毛毛

Spring Bean Life Cycle Explained - by - Lokesh Gupta

基于 spring centext 5.1.3.RELEASE


简介


在 spring 中,使用 Bean 代指 spring 所管理的类,如上一节的 ServiceImpl,同时,spring 也规定了 Bean 的生命周期,不同于普通类从载入到被垃圾回收器回收的生命周期,spring 实现了更加详尽的生命周期。spring bean 的生命周期如下:

  1. 实例化 bean 对象,即 new XX();
  2. 填充对象属性
  3. 检查Aware相关接口并设置相关依赖
  4. BeanPostProcessor 前置处理
  5. 检查是否是 InitializingBean 决定是否调用 afterPropertiesSet 方法,检查是否有自定义的 init-method,有的话调用
  6. BeanPosetProcessor 后置处理
  7. 注册必要的 Destruction 相关回调接口
  8. 使用
  9. 是否实现 DisposableBean 相关接口,是的话执行 destroy() 函数。
  10. 是否有自定义 destroy 方法,是的话执行。

详细解释参见大闲人柴毛毛知乎


组件简介


BeanFactory

BeanFactory 是 spring 最基本的一个库,BeanFactory 实现了 Bean 对象的管理,包括如何利用 Bean 的名字获得 Bean 对象等。BeanFactory 的接口如下:

public interface BeanFactory {

    String FACTORY_BEAN_PREFIX = "&";

    //根据 bean name 获得bean 对象
    Object getBean(String name) throws BeansException;
    
    //根据 bean name 获得 bean 对象并转化成正确类型
    <T> T getBean(String name, Class<T> requiredType) throws BeansException;

    //利用 bean name 获得 bean 对象,并用 args 覆盖一些配置
    Object getBean(String name, Object... args) throws BeansException;

    <T> T getBean(Class<T> requiredType) throws BeansException;

    <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

    <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

    <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);

    boolean containsBean(String name);

    //bean 是否为单例模式
    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

    //是否为 原型模式
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

    @Nullable
    Class<?> getType(String name) throws NoSuchBeanDefinitionException;

    String[] getAliases(String name);

}

依据 BeanFactory 所派生的接口非常复杂,大概有 20 个左右的类。典型的接口如下:

//顾名思义,层级 BeanFactory,可以获得上一级 BeanFatory,并且可以判断某名字的 Bean 是否在该 BeanFacory 中。
public interface HierarchicalBeanFactory extends BeanFactory {

    BeanFactory getParentBeanFactory();

    boolean containsLocalBean(String name);

}
//能够自动注解的类
public interface AutowireCapableBeanFactory extends BeanFactory {

    int AUTOWIRE_NO = 0;

    int AUTOWIRE_BY_NAME = 1;

    int AUTOWIRE_BY_TYPE = 2;

    int AUTOWIRE_CONSTRUCTOR = 3;

    @Deprecated
    int AUTOWIRE_AUTODETECT = 4;

    String ORIGINAL_INSTANCE_SUFFIX = ".ORIGINAL";

    <T> T createBean(Class<T> beanClass) throws BeansException;

    void autowireBean(Object existingBean) throws BeansException;

    Object configureBean(Object existingBean, String beanName) throws BeansException;


    //-------------------------------------------------------------------------
    // Specialized methods for fine-grained control over the bean lifecycle
    //-------------------------------------------------------------------------

    Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;

    Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;

    void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
            throws BeansException;

    void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;

    Object initializeBean(Object existingBean, String beanName) throws BeansException;

    Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException;

    Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException;

    void destroyBean(Object existingBean);


    //-------------------------------------------------------------------------
    // Delegate methods for resolving injection points
    //-------------------------------------------------------------------------

    <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;

    @Nullable
    Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException;

    @Nullable
    Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
            @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;

}
//可以计数的 BeanFactory
public interface ListableBeanFactory extends BeanFactory {

    boolean containsBeanDefinition(String beanName);

    int getBeanDefinitionCount();

    String[] getBeanDefinitionNames();

    String[] getBeanNamesForType(ResolvableType type);

    String[] getBeanNamesForType(@Nullable Class<?> type);

    String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);

    <T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;

    <T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
            throws BeansException;

    String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);

    Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;

    <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
            throws NoSuchBeanDefinitionException;

}
//最重要的一个接口,spring 中大部分的实例都是使用的该接口
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
        MessageSource, ApplicationEventPublisher, ResourcePatternResolver {

    @Nullable
    String getId();

    String getApplicationName();

    String getDisplayName();

    long getStartupDate();

    @Nullable
    ApplicationContext getParent();

    AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;

}

ConfigurableApplicationContext 继承自 ApplicationContext,增加了一些配置的功能,如设置 context ID,最重要的是增加了 addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor)void refresh() throws BeansException, IllegalStateException 方法,用于实现 context 的刷新和初始化之前的一些操作。

BeanDefinition

用于保存每一个 bean 的定义。

BeanWrapper

用于封装需要注入的类,并提供 set 方式,以避免用反射的方式设置属性。

AbstractBeanDefinitionReader

AbstractBeanDefinitionReader 实现了 BeanDefinitionReader 接口和 EnvironmentCapable 接口,主要作用是读取配置文件并生成对应 Bean 的配置。


处理流程分析


以如下的代码分析处理流程,代码如下:

package ioc;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring_ioc.xml");
        Service service = (Service) context.getBean("serviceImpl");
        service.doSomething();
    }

}
package ioc;

public interface Service {

    public void doSomething();

}
package ioc;

public class ServiceImpl implements Service {

    public void doSomething() {
        System.out.println(this.getClass().getName() + "#doSomething");
    }

}
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd
       ">
    <bean name="serviceImpl" class="ioc.ServiceImpl">

    </bean>

</beans>

Bean 的生命周期分为10个步骤,按照步骤一步一步说明 BeanFactory 如何管理 Bean。

初始化

这里的初始化指的是 Bean 生命周期中 Bean 实例准备就绪之前的所有动作。

准备工作

Bean 的初始化始于 ApplicationContext context = new ClassPathXmlApplicationContext("spring_ioc.xml"),总结来说就是读取配置文件并生成实例。

ClaaPathXmlApplicationContextAbstractXmlApplicationContext 的子类,作用就是从 classpath 中查找配置文件并对 Bean 进行初始化。

ClaaPathXmlApplicationContext 的初始化函数如下:

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
    this(new String[] {configLocation}, true, null);
}
public ClassPathXmlApplicationContext(
        String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
        throws BeansException {

    super(parent);
    setConfigLocations(configLocations);
    if (refresh) {
        refresh();
    }
}

实际上是调用继承的初始化函数,并对 Bean 刷新。

super(parent) 方法在 AbstractApplicationContext 中正真执行,代码如下:

public AbstractApplicationContext(@Nullable ApplicationContext parent) {
    this();
    setParent(parent);
}
public AbstractApplicationContext() {
    this.resourcePatternResolver = getResourcePatternResolver();
}

实际上作用只是获得一个 ResourcePatternResolver
setConfigLocations(configLocations) 用于设定 confifLocation 的位置,并存储。

最重要的函数是 refresh 方法,通过 refresh 更新 BeanFactoryrefresh 的方法实现在 AbstractApplicationContext 中,具体实现如下:

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        //step 1
        // Prepare this context for refreshing.
        prepareRefresh();

        //step 2
        // Tell the subclass to refresh the internal bean factory.
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        //step 3
        // Prepare the bean factory for use in this context.
        prepareBeanFactory(beanFactory);

        try {
            //step 4
            // Allows post-processing of the bean factory in context subclasses.
            postProcessBeanFactory(beanFactory);

            //step 5
            // Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory);

            //step 6
            // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);

            //step 7
            // Initialize message source for this context.
            initMessageSource();

            //step 8
            // Initialize event multicaster for this context.
            initApplicationEventMulticaster();

            //step 9
            // Initialize other special beans in specific context subclasses.
            onRefresh();

            //step 10
            // Check for listener beans and register them.
            registerListeners();

            //step 11
            // Instantiate all remaining (non-lazy-init) singletons.
            finishBeanFactoryInitialization(beanFactory);

            //step 12
            // Last step: publish corresponding event.
            finishRefresh();
        } catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                        "cancelling refresh attempt: " + ex);
            }

            // Destroy already created singletons to avoid dangling resources.
            destroyBeans();

            // Reset 'active' flag.
            cancelRefresh(ex);

            // Propagate exception to caller.
            throw ex;
        } finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
        }
    }
}

第一步

prepareRefresh()主要是做一些检查的工作,并将当前的 BeanFacory 的属性设置为激活。

第二步

obtainFreshBeanFactory 是真正的初始化函数,函数定义如下:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    return getBeanFactory();
}

更新 BeanFactory 并将 BeanFactory 返回。其中,refreshBeanFactory() 交给了子类实现。具体的实现在 AbstractRefreshableApplicationContext 中。具体代码如下:

@Override
protected final void refreshBeanFactory() throws BeansException {
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    try {
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        beanFactory.setSerializationId(getId());
        customizeBeanFactory(beanFactory);
        loadBeanDefinitions(beanFactory);
        synchronized (this.beanFactoryMonitor) {
            this.beanFactory = beanFactory;
        }
    } catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

当存在 beanFactory 时,首先先注销原来的 BeanFactory,接下来创建一个新的内部 BeanFactory,设置序列号,并在 customizeBeanFactory(beanFactory) 中设置是否允许覆盖定义(默认允许),最重要的是 loadBeanDefinitions 函数,他负责了读取配置并对 Bean 进行加载。

loadBeanDefinitions 函数由其子类 AbstractXmlApplicationContext 实现。主要功能实解析 xml 文件并产生 Bean Definition。

解析 xml 文件
loadBeanDefinitions() 函数的实现如下:

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // Create a new XmlBeanDefinitionReader for the given BeanFactory.
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

    // Configure the bean definition reader with this context's
    // resource loading environment.
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

    // Allow a subclass to provide custom initialization of the reader,
    // then proceed with actually loading the bean definitions.
    initBeanDefinitionReader(beanDefinitionReader);
    loadBeanDefinitions(beanDefinitionReader);
}

可以看到主要是生成一个 XmlBeanDefinitionReader 实例对 xml 文件进行解析。以下的函数都是实现在其父类 AbstractBeanDefinitionReader 中的方法,提供通用的加载策略。最重要的是 loadBeanDefinitions(beanDefinitionReader) 函数。函数定义如下:

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
    Resource[] configResources = getConfigResources();
    if (configResources != null) {
        reader.loadBeanDefinitions(configResources);
    }
    String[] configLocations = getConfigLocations();
    if (configLocations != null) {
        reader.loadBeanDefinitions(configLocations);
    }
}

因为使用 configLocation 加载配置,所以 configResources 为空,Resource 接口定义了资源是否存在,资源是否准备好,资源是否是文件等信息,一般用于网络资源的加载。我们只关心以 Stringp[] 作为参数的 loadBeanDefinitions 函数。
定义如下:

@Override
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
    Assert.notNull(locations, "Location array must not be null");
    int count = 0;
    for (String location : locations) {
        count += loadBeanDefinitions(location);
    }
    return count;
}

逻辑很简单,有多少个文件就执行多少次 loadDefinition 函数,并计数。真正的处理函数在 loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) 中。代码如下:

public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
    ResourceLoader resourceLoader = getResourceLoader();
    if (resourceLoader == null) {
        throw new BeanDefinitionStoreException(
                "Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
    }

    if (resourceLoader instanceof ResourcePatternResolver) {
        // Resource pattern matching available.
        try {
            Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
            int count = loadBeanDefinitions(resources);
            if (actualResources != null) {
                Collections.addAll(actualResources, resources);
            }
            if (logger.isTraceEnabled()) {
                logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
            }
            return count;
        }
        catch (IOException ex) {
            throw new BeanDefinitionStoreException(
                    "Could not resolve bean definition resource pattern [" + location + "]", ex);
        }
    } else {
        // Can only load single resources by absolute URL.
        Resource resource = resourceLoader.getResource(location);
        int count = loadBeanDefinitions(resource);
        if (actualResources != null) {
            actualResources.add(resource);
        }
        if (logger.isTraceEnabled()) {
            logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
        }
        return count;
    }
}

ClassPathXmlApplicationContext 的实现中,他既继承了 BeanFactory,也同时继承了 ResourceLoaderResourcePatternResolver 即可以实现资源的加载和将 url 封装成 Resource 的功能。

url 经过解析之后,实际上还是调用的 loadDefinifions(Resource[]),这时,Resource 中包含了 path 和类加载器。我们再看 loadDefinifions(Resource[]),定义如下:

@Override
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
    Assert.notNull(resources, "Resource array must not be null");
    int count = 0;
    for (Resource resource : resources) {
        count += loadBeanDefinitions(resource);
    }
    return count;
}

loadBeanDefinitions(Resource) 由其子类重写,用来加载真正的资源。XmlBeanDefinitionReader 实现如下:

@Override
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
    //EncodedResource 封装了 encode 方法和 encode 的编码类型
    return loadBeanDefinitions(new EncodedResource(resource));
}

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
    //resourcesCurrentlyBeingLoaded 是一个 ThreadLocal 变量,用于安全的线程中存储数据.
    Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
    if (currentResources == null) {
        currentResources = new HashSet<>(4);
        this.resourcesCurrentlyBeingLoaded.set(currentResources);
    }
    //将 encodedResource 添加到 ThreadLocal 中。
    if (!currentResources.add(encodedResource)) {
        throw new BeanDefinitionStoreException(
                "Detected cyclic loading of " + encodedResource + " - check your import definitions!");
    }
    try {
        InputStream inputStream = encodedResource.getResource().getInputStream();
        try {
            InputSource inputSource = new InputSource(inputStream);
            if (encodedResource.getEncoding() != null) {
                inputSource.setEncoding(encodedResource.getEncoding());
            }
            //解析数据
            return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
        } finally {
            inputStream.close();
        }
    } catch (IOException ex) {
        throw new BeanDefinitionStoreException(
                "IOException parsing XML document from " + encodedResource.getResource(), ex);
    } finally {
        currentResources.remove(encodedResource);
        if (currentResources.isEmpty()) {
            this.resourcesCurrentlyBeingLoaded.remove();
        }
    }
}

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
            throws BeanDefinitionStoreException {

    try {
        Document doc = doLoadDocument(inputSource, resource);
        int count = registerBeanDefinitions(doc, resource);
        if (logger.isDebugEnabled()) {
            logger.debug("Loaded " + count + " bean definitions from " + resource);
        }
        return count;
    }
    catch...
}

doLoadBeanDefinitions 主要有两个步骤,第一个步骤是获得 xml 的 Document 文档,第二个步骤是将文档中的 Bean 定义注册到 context 中。

第一个步骤的代码如下:

protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
    //生成 Document,利用 EntityResolver 解析 SAX 文件(DTD等),生成Document
    return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
            getValidationModeForResource(resource), isNamespaceAware());
}

第二个步骤的代码如下:

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
    int countBefore = getRegistry().getBeanDefinitionCount();
    documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
    return getRegistry().getBeanDefinitionCount() - countBefore;
}

Registry 是存储 Bean 的结构,在这里,默认使用 DefaultListableBeanFactory 实现。解析 Document 文件并根据解析结果将 BeanDefinition 存储在 Regist 中。

第三步

prepareBeanFactory 主要是对 beanFactory 做一些初始化,比如说设置 classLoader,忽略的接口,并提前注册一些 Bean,如使用 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory) 函数注册他自身,或者注册单例模式(使用 beanFactory.registerSingleton()函数)。代码如下:

/**
     * Configure the factory's standard context characteristics,
     * such as the context's ClassLoader and post-processors.
     * @param beanFactory the BeanFactory to configure
     */
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // Tell the internal bean factory to use the context's class loader etc.
    beanFactory.setBeanClassLoader(getClassLoader());
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    // Configure the bean factory with context callbacks.
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

    // BeanFactory interface not registered as resolvable type in a plain factory.
    // MessageSource registered (and found for autowiring) as a bean.
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    // Register early post-processor for detecting inner beans as ApplicationListeners.
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    // Detect a LoadTimeWeaver and prepare for weaving, if found.
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        // Set a temporary ClassLoader for type matching.
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }

    // Register default environment beans.
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
}

第四步

postProcessBeanFactory(beanFactory) 允许子类对 beanFactory 做一些自定义的操作,这里没有实现,是一个空方法。

第五步

invokeBeanFactoryPostProcessors 实例化所有注册的的 BeanFactoryPostProcessor Bean。

第六步

registerBeanPostProcessors(beanFactory) 注册预处理器。

第七步

initMessageSource(),初始化数据源。

第八步

initApplicationEventMulticaster(),初始化多播器。

第九步

onRefresh(),更新。子类未实现。

第十步

registerListeners() 第九步,注册监听器

第十一步

finishBeanFactoryInitialization() 初始化所有剩下的Beans,集体实现如下:

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // Initialize conversion service for this context.
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
            beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        beanFactory.setConversionService(
                beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }

    // Register a default embedded value resolver if no bean post-processor
    // (such as a PropertyPlaceholderConfigurer bean) registered any before:
    // at this point, primarily for resolution in annotation attribute values.
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    }

    // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }

    // Stop using the temporary ClassLoader for type matching.
    beanFactory.setTempClassLoader(null);

    // Allow for caching all bean definition metadata, not expecting further changes.
    //此时禁止配置,以防止出现不可预料的问题
    beanFactory.freezeConfiguration();

    //初始化剩下的单例 Bean
    // Instantiate all remaining (non-lazy-init) singletons.
    beanFactory.preInstantiateSingletons();
}

重点函数在 preInstantiateSingletons 上。这个函数负责真正加载单例 Bean。代码如下:

@Override
public void preInstantiateSingletons() throws BeansException {

    // Iterate over a copy to allow for init methods which in turn register new bean definitions.
    // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

    // Trigger initialization of all non-lazy singleton beans...
    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            if (isFactoryBean(beanName)) {
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                if (bean instanceof FactoryBean) {
                    final FactoryBean<?> factory = (FactoryBean<?>) bean;
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                        ((SmartFactoryBean<?>) factory)::isEagerInit,
                                getAccessControlContext());
                    } else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
            } else {
                getBean(beanName);
            }
        }
    }

    // Trigger post-initialization callback for all applicable beans...
    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
            final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    smartSingleton.afterSingletonsInstantiated();
                    return null;
                }, getAccessControlContext());
            } else {
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}

首先获得所有 Bean 的名字,通过名字获得 BeanDefinition,如果不是 FactoryBean 的话,执行 getBean(beanName)

getBean()doGetBean() 具体实现,实现是在 AbstractBeanFactory 中,具体实现如下:

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
        @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

    final String beanName = transformedBeanName(name);
    Object bean;

    // phase 1
    // Eagerly check singleton cache for manually registered singletons.
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        if (logger.isTraceEnabled()) {
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    } else {
        // Fail if we're already creating this bean instance:
        // We're assumably within a circular reference.
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // phase 2
        // Check if bean definition exists in this factory.
        BeanFactory parentBeanFactory = getParentBeanFactory();
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // Not found -> check parent.
            String nameToLookup = originalBeanName(name);
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                        nameToLookup, requiredType, args, typeCheckOnly);
            }
            else if (args != null) {
                // Delegation to parent with explicit args.
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else if (requiredType != null) {
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            } else {
                return (T) parentBeanFactory.getBean(nameToLookup);
            }
        }

        if (!typeCheckOnly) {
            markBeanAsCreated(beanName);
        }

        try {
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);
            
            // phase 3
            // Guarantee initialization of beans that the current bean depends on.
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                for (String dep : dependsOn) {
                    if (isDependent(beanName, dep)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }
                    registerDependentBean(dep, beanName);
                    try {
                        getBean(dep);
                    } catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                    }
                }
            }

            // phase 4
            // Create bean instance.
            if (mbd.isSingleton()) {
                sharedInstance = getSingleton(beanName, () -> {
                    try {
                        return createBean(beanName, mbd, args);
                    } catch (BeansException ex) {
                        // Explicitly remove instance from singleton cache: It might have been put there
                        // eagerly by the creation process, to allow for circular reference resolution.
                        // Also remove any beans that received a temporary reference to the bean.
                        destroySingleton(beanName);
                        throw ex;
                    }
                });
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            } else if (mbd.isPrototype()) {
                // It's a prototype -> create a new instance.
                Object prototypeInstance = null;
                try {
                    beforePrototypeCreation(beanName);
                    prototypeInstance = createBean(beanName, mbd, args);
                } finally {
                    afterPrototypeCreation(beanName);
                }
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            } else {
                String scopeName = mbd.getScope();
                final Scope scope = this.scopes.get(scopeName);
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                }
                try {
                    Object scopedInstance = scope.get(beanName, () -> {
                        beforePrototypeCreation(beanName);
                        try {
                            return createBean(beanName, mbd, args);
                        } finally {
                            afterPrototypeCreation(beanName);
                        }
                    });
                    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                } catch (IllegalStateException ex) {
                    throw new BeanCreationException(beanName,
                            "Scope '" + scopeName + "' is not active for the current thread; consider " +
                            "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                            ex);
                }
            }
        } catch (BeansException ex) {
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
    }

    // Check if required type matches the type of the actual bean instance.
    if (requiredType != null && !requiredType.isInstance(bean)) {
        try {
            T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
            if (convertedBean == null) {
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
            return convertedBean;
        } catch (TypeMismatchException ex) {
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    }
    return (T) bean;
}

代码非常的长,将其分段。

第一阶段,主要是在人工注入的 Register 中有没有 Bean,如果有,返回。

第二阶段,检查父节点中有没有 Bean,有,返回。

第三阶段,主要是检查 有没有循环依赖,循环依赖的报错就是在这产生的。并且初始化所有的依赖 Bean。

第四阶段,调用 createBean(beanName, mbd, args) 新建一个单例 bean。在这一阶段,做了生命周期中大量的工作,包括初始化 Bean、填充属性、如果继承自 BeanNameAware,设置 Bean name、如果继承自 BeanFactoryAware,设置 BeanFactory、调用BeanPostProcessorpostProcessBeforeInitialization 做一些前期处理、如果继承了 InitializingBean 接口,则调用 afterPropertiesSet 方法、如果继承了 BeanPostProcess 接口,则调用 postProcessAfterInitialization 方法。可以说,这一步,实现了 Bean 大部分的生命周期函数。

第十二步

finishRefresh(),主要是做一些收尾工作。

至此,初始化 Bean 的工作九到此结束。

使用过程

使用过程和初始化复用了大量的代码,主要是 getBean() 函数的代码,唯一的区别是在初始化时,要新建实例,而使用时直接从缓存中读取数据并返回。

相关文章

网友评论

      本文标题:spring 源码分析(二)Core

      本文链接:https://www.haomeiwen.com/subject/tqermqtx.html