0


Spring启动流程解析(总)

一,Spring启动流程概述

Spring的IoC容器在实现控制反转和依赖注入的过程中,可以划分为两个阶段:

  • 容器启动阶段
  • Bean实例化阶段

容器初始化

  1. 加载配置
  2. 分析配置信息
  3. 将Bean信息装配到BeanDefinition
  4. 将Bean信息注册到相应的BeanDefinitionRegistry
  5. 其他后续处理

容器实例化

  1. 根据策略实例化对象
  2. 装配依赖
  3. Bean初始化前处理
  4. 对象初始化
  5. 对象其他处理
  6. 注册回调接口

二,Spring启动流程详解

启动流程源码概览

ClassPathXmlApplicationContext

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
            throws BeansException {
    super(parent);
    setConfigLocations(configLocations);
    if (refresh) {
        refresh();
    }
}

public ClassPathXmlApplicationContext(String[] paths, Class<?> clazz, ApplicationContext parent)
            throws BeansException {
    super(parent);
    Assert.notNull(paths, "Path array must not be null");
    Assert.notNull(clazz, "Class argument must not be null");
    this.configResources = new Resource[paths.length];
    for (int i = 0; i < paths.length; i++) {
        this.configResources[i] = new ClassPathResource(paths[i], clazz);
    }
    refresh();
}

AbstractApplicationContext

public void refresh() throws BeansException, IllegalStateException {
    // 方法加锁避免多线程同时刷新Spring上下文
    synchronized (this.startupShutdownMonitor) {
        // 准备上下文刷新
        prepareRefresh();

        // 告诉子类刷新内部的beanFactory返回新的BeanFactory
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // 在当前上下文中准备要beanFactory
        prepareBeanFactory(beanFactory);

        try {
            // 允许在上下文子类中对beanFactory进行后置处理
            postProcessBeanFactory(beanFactory);

            // 在上下文中将BeanFactory处理器注册为Bean
            invokeBeanFactoryPostProcessors(beanFactory);

            // 注册Bean处理器用于拦截Bean的创建
            registerBeanPostProcessors(beanFactory);

            // 在上下文中初始化国际化信息
            initMessageSource();

            // 在上下文中初始化event multicaster(事件多播器)
            initApplicationEventMulticaster();

            // 在指定的上下文子类中初始化其他指定的beans
            onRefresh();

            // 检查并注册事件监听
            registerListeners();

            // 实例化所有剩余的(非延迟初始化)单例
            finishBeanFactoryInitialization(beanFactory);

            // 最后一步:发布相应的事件
            finishRefresh();
        }
        catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                    "cancelling refresh attempt: " + ex);
            }

            // 如果出现异常则销毁已创建的单例
            destroyBeans();

            // 重置活动标志。
            cancelRefresh(ex);

            // 将异常传递给调用者
            throw ex;
        }
        finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
        }
    }
}

整个refresh()的代码都是同步的,而对应的同步对象是startupShutdownMonitor。startupShutdownMonitor只在refresh()和close()两个方法里被用到,而它是用来同步applicationContext的刷新和销毁。

面试题

Spring的registerShutdownHook和close有什么区别?

close()被调用时会立即关闭或者停止ApplicationContext;而调用registerShutdownHook()将在稍后JVM关闭时关闭或停止ApplicationContext,该方法主要通过JVM ShutdownHook来实现。

ShutdownHook

Java 语言提供一种 ShutdownHook(钩子)机制,当 JVM 接受到系统的关闭通知之后,调用 ShutdownHook 内的方法,用以完成清理操作,从而实现平滑退出应用。

第一步 刷新准备

protected void prepareRefresh() {
    // 设置启动时间。当前毫秒数代表当前applicationContext的创建时间
    this.startupDate = System.currentTimeMillis();
    // 设置容器关闭标志
    this.closed.set(false);
    // 设置启动标志
    this.active.set(true);

    if (logger.isInfoEnabled()) {
        logger.info("Refreshing " + this);
    }

    // 初始化属性资源
    initPropertySources();

    // 验证所有的属性是否都是可解析的
    getEnvironment().validateRequiredProperties();

    // ApplicationEvent初始化
    this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
}

第二步 获取BeanFactory

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (logger.isDebugEnabled()) {
        logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
    }
    return beanFactory;
}

该方法对BeanFactory进行刷新。如果刷新前已经存在一个BeanFactory则需要先进行关闭操作,而后初始化一个新BeanFactory。

protected final void refreshBeanFactory() throws BeansException {
    // 判断是否已经存在一个BeanFactory 
    if (hasBeanFactory()) {
        // 销毁已经存在BeanFactory中的所有Bean
        destroyBeans();
        // 关闭BeanFactory
        closeBeanFactory();
    }
    try {
        // 创建新的BeanFactory对象(DefaultListableBeanFactory)
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        // 给BeanFactory设置Id
        beanFactory.setSerializationId(getId());
        // 该方法主要对2个标志进行设置:allowBeanDefinitionOverriding和allowCircularReferences
        // allowBeanDefinitionOverriding:是否允许使用相同名称重新注册不同的bean(Spring默认true,SpringBoot默认false)
        // allowCircularReferences:是否允许循环依赖
        customizeBeanFactory(beanFactory);
        // 加载配置文件
        loadBeanDefinitions(beanFactory);
        synchronized (this.beanFactoryMonitor) {
            // 新创建的BeanFactory赋给成员变量beanFactory
            this.beanFactory = beanFactory;
        }
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

DefaultSingletonBeanRegistry

// 当前这个单例是否正在被销毁
// true:表示单例已经执行了destroy方法,或者出现异常时执行了destroySingleton方法
private boolean singletonsCurrentlyInDestruction = false;

// 缓存两个Bean之间的包含关系。如:一个Bean中包含了一个内部Bean。
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>(16);

// 缓存Bean与其他依赖Bean的关系
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>(64);

// 缓存被依赖Bean与其他依赖Bean的关系
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>(64);

// 销毁所有的Bean实例
public void destroySingletons() {
    if (logger.isDebugEnabled()) {
        logger.debug("Destroying singletons in " + this);
    }
    synchronized (this.singletonObjects) {
        // 设置销毁标志
        this.singletonsCurrentlyInDestruction = true;
    }

    // 销毁disposableBeans缓存中所有单例bean
    String[] disposableBeanNames;
    synchronized (this.disposableBeans) {
        disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
    }
    for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
        destroySingleton(disposableBeanNames[i]);
    }

    // 清空包含关系
    this.containedBeanMap.clear();
    // 清空依赖和被依赖关系
    this.dependentBeanMap.clear();
    this.dependenciesForBeanMap.clear();

    // 清空缓存
    clearSingletonCache();
}

加载配置

AbstractXmlApplicationContext

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
    // 以Resource方式加载配置
    Resource[] configResources = getConfigResources();
    if (configResources != null) {
        // 读取配置文件
        reader.loadBeanDefinitions(configResources);
    }
    // 以String方式加载配置
    String[] configLocations = getConfigLocations();
    if (configLocations != null) {
        // 读取配置文件
        reader.loadBeanDefinitions(configLocations);
    }
}

AbstractBeanDefinitionReader

@Override
// 通过String数组参数locations加载Bean,并返回加载Bean的数量
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
    Assert.notNull(locations, "Location array must not be null");
    int counter = 0;
    for (String location : locations) {
        // 加载BeanDefinintion
        counter += loadBeanDefinitions(location);
    }
    // 返回加载Bean的数量
    return counter;
}

@Override
// 通过Resource数组参数locations加载Bean,并返回加载Bean的数量
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
    Assert.notNull(resources, "Resource array must not be null");
    int counter = 0;
    for (Resource resource : resources) {
        // 加载BeanDefinintion
        counter += loadBeanDefinitions(resource);
    }
    // 返回加载Bean的数量
    return counter;
}

XmlBeanDefinitionReader

// 从配置文件中加载Bean
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
    Assert.notNull(encodedResource, "EncodedResource must not be null");
    if (logger.isInfoEnabled()) {
        logger.info("Loading XML bean definitions from " + encodedResource);
    }

    Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
    if (currentResources == null) {
        currentResources = new HashSet<EncodedResource>(4);
        this.resourcesCurrentlyBeingLoaded.set(currentResources);
    }
    if (!currentResources.add(encodedResource)) {
        throw new BeanDefinitionStoreException(
            "Detected cyclic loading of " + encodedResource + " - check your import definitions!");
    }
    try {
        // 将Resource资源转化为输入流InputStream
        InputStream inputStream = encodedResource.getResource().getInputStream();
        try {
            InputSource inputSource = new InputSource(inputStream);
            if (encodedResource.getEncoding() != null) {
                inputSource.setEncoding(encodedResource.getEncoding());
            }
            // 执行加载Bean的过程
            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();
        }
    }
}

// 加载Bean的函数
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
    throws BeanDefinitionStoreException {
    try {
        // 加载XML文件,构造XML Document对象
        Document doc = doLoadDocument(inputSource, resource);
        // 注册Bean
        return registerBeanDefinitions(doc, resource);
    }
    // 抛出各种异常
    ......
}

Bean的解析与注册

DefaultBeanDefinitionDocumentReader

// XML配置文件中beans元素
public static final String NESTED_BEANS_ELEMENT = "beans";
// XML配置文件中alias别名元素
public static final String ALIAS_ELEMENT = "alias";
// XML配置文件中name属性
public static final String NAME_ATTRIBUTE = "name";
// XML配置文件中alias属性
public static final String ALIAS_ATTRIBUTE = "alias";
// XML配置文件中import元素
public static final String IMPORT_ELEMENT = "import";
// XML配置文件中resource属性
public static final String RESOURCE_ATTRIBUTE = "resource";
// XML配置文件中profile属性
public static final String PROFILE_ATTRIBUTE = "profile";

protected void doRegisterBeanDefinitions(Element root) {
    BeanDefinitionParserDelegate parent = this.delegate;
    // 创建Bean解析代理工具类
    this.delegate = createDelegate(getReaderContext(), root, parent);

    if (this.delegate.isDefaultNamespace(root)) {
        // 解析profile属性
        String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
        if (StringUtils.hasText(profileSpec)) {
            String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
                profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
            if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
                if (logger.isInfoEnabled()) {
                    logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
                                "] not matching: " + getReaderContext().getResource());
                }
                return;
            }
        }
    }

    preProcessXml(root);
    // 解析XML并执行Bean注册
    parseBeanDefinitions(root, this.delegate);
    postProcessXml(root);

    this.delegate = parent;
}

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    // root根节点是默认标签
    if (delegate.isDefaultNamespace(root)) {
        NodeList nl = root.getChildNodes();
        // 遍历XML Document的每个节点
        for (int i = 0; i < nl.getLength(); i++) {
            Node node = nl.item(i);
            if (node instanceof Element) {
                Element ele = (Element) node;
                if (delegate.isDefaultNamespace(ele)) {
                    // 解析默认标签
                    parseDefaultElement(ele, delegate);
                }
                else {
                    // 解析自定义标签
                    delegate.parseCustomElement(ele);
                }
            }
        }
    }
    // root根节点是自定义标签
    else {
        delegate.parseCustomElement(root);
    }
}

// 解析XML配置文件的节点元素
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
    // 如果是Import元素
    if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
        importBeanDefinitionResource(ele);
    }
    // 如果是Alias别名元素
    else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
        processAliasRegistration(ele);
    }
    // 如果是Bean元素
    else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
        processBeanDefinition(ele, delegate);
    }
    // 如果是嵌套Bean元素(Beans)
    else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
        // recurse
        doRegisterBeanDefinitions(ele);
    }
}

Import解析

虽然每个单独的XML配置文件都代表体系结构中的逻辑层或模块,但我们可以从多个XML片段中加载Bean定义。如项目中有多个Resource位置,可以使用一个或多个<import />从另外的XML文件中加载Bean定义。

标签用法示例:

<import resource="applicationDao.xml" />
<import resource="applicationService.xml" />

解析标签的源码:

DefaultBeanDefinitionDocumentReader

protected void importBeanDefinitionResource(Element ele) {
    String location = ele.getAttribute(RESOURCE_ATTRIBUTE);
    if (!StringUtils.hasText(location)) {
        getReaderContext().error("Resource location must not be empty", ele);
        return;
    }

    // 解析路径和占位符
    location = getReaderContext().getEnvironment().resolveRequiredPlaceholders(location);

    // 解析好的资源要放到Set里面
    Set<Resource> actualResources = new LinkedHashSet<Resource>(4);

    // 解析location是相对路径还是绝对路径
    boolean absoluteLocation = false;
    try {
        absoluteLocation = ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute();
    }
    catch (URISyntaxException ex) {
        // cannot convert to an URI, considering the location relative
        // unless it is the well-known Spring prefix "classpath*:"
    }

    // 如果是绝对路径
    if (absoluteLocation) {
        try {
            // 直接根据路径加载相应的配置文件
            int importCount = getReaderContext().getReader().loadBeanDefinitions(location, actualResources);
            if (logger.isDebugEnabled()) {
                logger.debug("Imported " + importCount + " bean definitions from URL location [" + location + "]");
            }
        }
        catch (BeanDefinitionStoreException ex) {
            getReaderContext().error(
                "Failed to import bean definitions from URL location [" + location + "]", ele, ex);
        }
    }
    else {
        try {
            int importCount;
            // 如果是相对路径,则先根据路径得到Resource
            Resource relativeResource = getReaderContext().getResource().createRelative(location);
            // 如果Resource存在
            if (relativeResource.exists()) {
                importCount = getReaderContext().getReader().loadBeanDefinitions(relativeResource);
                actualResources.add(relativeResource);
            }
            else {
                // Resource类解析不成功,在classpath路径中去加载。如果没有则抛出异常
                String baseLocation = getReaderContext().getResource().getURL().toString();
                importCount = getReaderContext().getReader().loadBeanDefinitions(
                    StringUtils.applyRelativePath(baseLocation, location), actualResources);
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Imported " + importCount + " bean definitions from relative location [" + location + "]");
            }
        }
        catch (IOException ex) {
            getReaderContext().error("Failed to resolve current resource location", ele, ex);
        }
        catch (BeanDefinitionStoreException ex) {
            getReaderContext().error("Failed to import bean definitions from relative location [" + location + "]",
                                     ele, ex);
        }
    }
    Resource[] actResArray = actualResources.toArray(new Resource[actualResources.size()]);
    getReaderContext().fireImportProcessed(location, actResArray, extractSource(ele));
}

Alias别名注册

每个bean具有一个或多个标识符。这些标识符在承载Bean的容器内必须是唯一的。 Bean通常只有一个标识符,但是如果需要多个标识符,则多余的标识符可以被视为别名。

标签用法示例:

<alias name="dataSource" alias="systemA-dataSource"/>
<alias name="dataSource" alias="systemB-dataSource"/>

在Bean定义中,可以通过使用id属性最多指定的一个名称,同时可以通过name属性中定义任意数量的其他名称来为Bean提供多个名称。但在定义Bean的地方指定所有别名可能并不能满足需求,有时需要在其他地方为Bean定义别名。

解析标签的源码:

SimpleAliasRegistry

// 存放别名的缓存
private final Map<String, String> aliasMap = new ConcurrentHashMap<String, String>

// 根据Bean的别名进行注册
public void registerAlias(String name, String alias) {
    Assert.hasText(name, "'name' must not be empty");
    Assert.hasText(alias, "'alias' must not be empty");
    synchronized (this.aliasMap) {
        // 如果别名和名字相同
        if (alias.equals(name)) {
            this.aliasMap.remove(alias);
        }
        else {
            // 如果别名和名字不相同,根据别名获取Bean名称
            String registeredName = this.aliasMap.get(alias);
            if (registeredName != null) {
                // 如果缓存中已经存在该别名,不需要注册到缓存
                if (registeredName.equals(name)) {
                    // An existing alias - no need to re-register
                    return;
                }
                // 如果不允许相同的Bean使用不同的名称则抛出异常
                if (!allowAliasOverriding()) {
                    throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" +
                                                    name + "': It is already registered for name '" + registeredName + "'.");
                }
            }
            // 对别名进行循环检查
            checkForAliasCircle(name, alias);
            // 把别名放入别名缓存
            this.aliasMap.put(alias, name);
        }
    }
}

// 别名循环检查
public boolean hasAlias(String name, String alias) {
    for (Map.Entry<String, String> entry : this.aliasMap.entrySet()) {
        // 获取Bean注册名
        String registeredName = entry.getValue();
        // 判断name参数和Bean注册名是否相同
        if (registeredName.equals(name)) {
            // 获取别名
            String registeredAlias = entry.getKey();
            // 判断别名是否相同
            // 递归调用hasAlias
            if (registeredAlias.equals(alias) || hasAlias(registeredAlias, alias)) {
                return true;
            }
        }
    }
    return false;
}

别名循环检查:A为名称,B为A的别名,需要注册别名<B, A>

  1. 检查B是否有别名,如果没有则返回false
  2. 如果B有别名C,检查C是否与A相同。如果相同返回true,说明有别名循环。如果不相同递归hasAlias(C, B)方法
  3. 如果C无别名,返回false;如果C有别名D且等于A,返回true。如果不相同继续递归hasAlias(D, B)

Bean注册

Spring会自动检测构造型类,并向容器注册相应的BeanDefinition。

DefaultBeanDefinitionDocumentReader

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    // 解析XML中的BeanDefinition元素
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    if (bdHolder != null) {
        bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
        try {
            // 注册BeanDefinition
            BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
        }
        catch (BeanDefinitionStoreException ex) {
            getReaderContext().error("Failed to register bean definition with name '" +
                                     bdHolder.getBeanName() + "'", ele, ex);
        }
        // 发送注册事件
        getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    }
}

BeanDefinitionParserDelegate

基于单一职责的缘故,BeanDefinitionParserDelegate专门负责解析XML元素的工作,而DefaultBeanDefinitionDocumentReader则主要负责读取XML配置文件的职责。

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
    // 获取id属性
    String id = ele.getAttribute(ID_ATTRIBUTE);
    // 获取name属性
    String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

    // 定义别名list
    List<String> aliases = new ArrayList<String>();
    if (StringUtils.hasLength(nameAttr)) {
        // 因为可以多个别名用,所以解析成别名数组
        String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
        aliases.addAll(Arrays.asList(nameArr));
    }

    // beanName默认为id
    String beanName = id;
    // 如果没有beanName,那么取出别名数组中的第一个作为beanName
    if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
        beanName = aliases.remove(0);
        if (logger.isDebugEnabled()) {
            logger.debug("No XML 'id' specified - using '" + beanName +
                         "' as bean name and " + aliases + " as aliases");
        }
    }

    if (containingBean == null) {
        checkNameUniqueness(beanName, aliases, ele);
    }

    AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
    if (beanDefinition != null) {
        if (!StringUtils.hasText(beanName)) {
            try {
                if (containingBean != null) {
                    // 生成Bean名
                    beanName = BeanDefinitionReaderUtils.generateBeanName(
                        beanDefinition, this.readerContext.getRegistry(), true);
                }
                else {
                    // 生成Bean名
                    beanName = this.readerContext.generateBeanName(beanDefinition);
                    String beanClassName = beanDefinition.getBeanClassName();
                    if (beanClassName != null &&
                        beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
                        !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
                        aliases.add(beanClassName);
                    }
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Neither XML 'id' nor 'name' specified - " +
                                 "using generated bean name [" + beanName + "]");
                }
            }
            catch (Exception ex) {
                error(ex.getMessage(), ele);
                return null;
            }
        }
        String[] aliasesArray = StringUtils.toStringArray(aliases);
        return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
    }

    return null;
}

// 解析Bean定义不考虑名称或别名。如果在Bean解析过程中产生异常,则返回null
public AbstractBeanDefinition parseBeanDefinitionElement(
    Element ele, String beanName, BeanDefinition containingBean) {

    this.parseState.push(new BeanEntry(beanName));

    String className = null;
    // 解析Bean的class属性
    if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
        className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
    }

    try {
        String parent = null;
        // 解析parent属性
        if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
            parent = ele.getAttribute(PARENT_ATTRIBUTE);
        }
        // 为指定的类名和Parent名称创建一个BeanDefinition
        AbstractBeanDefinition bd = createBeanDefinition(className, parent);

        // 解析Bean元素的属性并应用于Bean
        parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
        // 设置Bean的描述信息
        bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

        // 解析Bean定义的元数据信息(meta以键值对形式存在)
        parseMetaElements(ele, bd);
        // 解析lookup-method元素
        parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
        // 解析replaced-method元素
        parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

        // 解析构造函数参数
        parseConstructorArgElements(ele, bd);
        // 解析property元素
        parsePropertyElements(ele, bd);
        // 解析qualifier元素
        parseQualifierElements(ele, bd);

        bd.setResource(this.readerContext.getResource());
        bd.setSource(extractSource(ele));

        return bd;
    }
    catch (ClassNotFoundException ex) {
        error("Bean class [" + className + "] not found", ele, ex);
    }
    catch (NoClassDefFoundError err) {
        error("Class that bean class [" + className + "] depends on not found", ele, err);
    }
    catch (Throwable ex) {
        error("Unexpected failure during bean definition parsing", ele, ex);
    }
    finally {
        this.parseState.pop();
    }

    return null;
}

BeanDefinitionReaderUtils

该类的主要职责用于生产新的BeanDefiniti实例,给Bean生成一个名称及调用BeanDefinitionRegistry进行Bean的注册。

public static String generateBeanName(
    BeanDefinition definition, BeanDefinitionRegistry registry, boolean isInnerBean)
    throws BeanDefinitionStoreException {

    String generatedBeanName = definition.getBeanClassName();
    if (generatedBeanName == null) {
        // 如果有父类,名称为:definition.getParentName() + “$child”
        if (definition.getParentName() != null) {
            generatedBeanName = definition.getParentName() + "$child";
        }
        // 如果有指定的工厂类,名称为:definition.getFactoryBeanName() + “$created”
        else if (definition.getFactoryBeanName() != null) {
            generatedBeanName = definition.getFactoryBeanName() + "$created";
        }
    }
    if (!StringUtils.hasText(generatedBeanName)) {
        throw new BeanDefinitionStoreException("Unnamed bean definition specifies neither " +
                                               "'class' nor 'parent' nor 'factory-bean' - can't generate bean name");
    }

    String id = generatedBeanName;
    if (isInnerBean) {
        // 如果是innerBean,名称为
        id = generatedBeanName + GENERATED_BEAN_NAME_SEPARATOR + ObjectUtils.getIdentityHexString(definition);
    }
    else {
        // 如果不是InnerBean则为顶层Bean,使用简单的类名。计数器加1
        int counter = -1;
        while (counter == -1 || registry.containsBeanDefinition(id)) {
            counter++;
            id = generatedBeanName + GENERATED_BEAN_NAME_SEPARATOR + counter;
        }
    }
    return id;
}
  • parent

Bean定义可以包含许多配置信息,包括容器相关的信息(比如初始化方法,静态工厂方法等等)以及构造函数参数和属性的值。子Bean可以定义从父Bean定义中继承配置数据,而后它可以根据需要覆盖某些值,或添加其他值。使用父子Bean可以节省很多输入工作。

  • lookup-method

lookup-method注入是容器重写Bean上的方法的一种能力,它可以在容器中根据一个Bean的名字返回查找结果。lookup-method通常涉及Prototype Bean。Spring框架通过使用CGLIB来覆盖该方法的子类以实现lookup-method的注入。该功能可用于在一些可插拔的功能上解除依赖。

  • replace-method

用于在运行时调用使用新的方法替换原有的方法,还能动态的改变原有方法的逻辑。

DefaultListableBeanFactory

// 手动注册的单例名称列表
private volatile Set<String> manualSingletonNames = new LinkedHashSet<String>(16);

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
            throws BeanDefinitionStoreException {

    Assert.hasText(beanName, "Bean name must not be empty");
    Assert.notNull(beanDefinition, "BeanDefinition must not be null");

    if (beanDefinition instanceof AbstractBeanDefinition) {
        try {
            // 对于AbstractBeanDefinition属性中的methodOverrides校验
            // 校验methodOverrides是否与工厂方法并存或者methodOverrides对应的方法根本不存在
            ((AbstractBeanDefinition) beanDefinition).validate();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                                                   "Validation of bean definition failed", ex);
        }
    }

    // 从缓存中根据beanName获取BeanDefinition
    BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
    if (existingDefinition != null) {
        // 如果BeanDefinition存在并且不允许同名覆盖,则抛出异常
        if (!isAllowBeanDefinitionOverriding()) {
            throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                                                   "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
                                                   "': There is already [" + existingDefinition + "] bound.");
        }
        // Bean的角色检查
        else if (existingDefinition.getRole() < beanDefinition.getRole()) {
            // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
            if (logger.isWarnEnabled()) {
                logger.warn("Overriding user-defined bean definition for bean '" + beanName +
                            "' with a framework-generated bean definition: replacing [" +
                            existingDefinition + "] with [" + beanDefinition + "]");
            }
        }
        // 如果名字相同,但是BeanDefinition不同打印覆盖日志
        else if (!beanDefinition.equals(existingDefinition)) {
            if (logger.isInfoEnabled()) {
                logger.info("Overriding bean definition for bean '" + beanName +
                            "' with a different definition: replacing [" + existingDefinition +
                            "] with [" + beanDefinition + "]");
            }
        }
        else {
            if (logger.isDebugEnabled()) {
                logger.debug("Overriding bean definition for bean '" + beanName +
                             "' with an equivalent definition: replacing [" + existingDefinition +
                             "] with [" + beanDefinition + "]");
            }
        }
        // 在缓存中注册Bean
        this.beanDefinitionMap.put(beanName, beanDefinition);
    }
    else {
        // 检查工厂的Bean创建阶段是否已经开始
        if (hasBeanCreationStarted()) {
            // 进入创建阶段,此时无法再修改启动时集合元素(为了稳定迭代)
            synchronized (this.beanDefinitionMap) {
                this.beanDefinitionMap.put(beanName, beanDefinition);
                List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1);
                updatedDefinitions.addAll(this.beanDefinitionNames);
                updatedDefinitions.add(beanName);
                this.beanDefinitionNames = updatedDefinitions;
                // beanName在manualSingletonNames中,说明是手动注册
                if (this.manualSingletonNames.contains(beanName)) {
                    Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames);
                    updatedSingletons.remove(beanName);
                    this.manualSingletonNames = updatedSingletons;
                }
            }
        }
        else {
            // 工厂还未到创建阶段,仍然在注册阶段
            this.beanDefinitionMap.put(beanName, beanDefinition);
            this.beanDefinitionNames.add(beanName);
            this.manualSingletonNames.remove(beanName);
        }
        this.frozenBeanDefinitionNames = null;
    }

    // 待注册的Bean的已经在beanDefinitionMap缓存中存在,或者已经存在于单例Bean缓存中
    if (existingDefinition != null || containsSingleton(beanName)) {
        // 重置给定Bean的所有BeanDefinition缓存,包括从其派生的Bean的缓存
        resetBeanDefinition(beanName);
    }
}

AbstractBeanFactory

// 保存在至少被创建过一次的beanName
// 如果这个集合中存在beanName,那么说明已经进入了Bean创建阶段
private final Set<String> alreadyCreated =
            Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(256))

第三步 准备BeanFactory

这个阶段主要是当Spring获取了BeanFactory之后,还要做些处理工作(配置工厂的上下文),如:上下文的ClassLoader和BeanPostProcessor。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 内部BeanFactory使用Context上下文的类加载器
    beanFactory.setBeanClassLoader(getClassLoader());
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    // 配置BeanFactory的Context上下文回调
    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接口不在普通工厂中注册为可解析类型
    // MessageSource 注册(找到并自动装配)为一个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.
    // 注册早期的后处理器用来将内部Bean检测为ApplicationListeners。
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    // 如果发现LoadTimeWeaver,则准备织入
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        // 给类型匹配设置一个临时的ClassLoader
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }

    // 注册默认的environment
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    // 注册systemProperties
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    // 注册systemEnvironment
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
}

BeanExpressionResolver

通过将值作为表达式进行评估来解析值。它的唯一实现类是StandardBeanExpressionResolver。

PropertyEditor

Spring使用PropertyEditor的来实现对象和字符串之间的转换。有时用与对象本身不同的方式表示属性可能更为方便。如:“2019-09-13”字符串形式阅读起来更友好,但也可以将任何方便阅读的日期表现形式转换为日期对象。

Spring提供了很多内置的PropertyEditor,它们都位于org.springframework.beans.propertyeditors包中。默认情况下,大多数由BeanWrapperImpl注册。

描述

ByteArrayPropertyEditor

字节数组属性编辑器。字符串将地转换为相应的字节形式。默认情况下由BeanWrapperImpl注册。

ClassEditor

将表示类的字符串解析为实际类,反之亦然。当找不到类时,将抛出IllegalArgumentException。默认情况下由BeanWrapperImpl注册。

CustomBooleanEditor

布尔属性编辑器。默认情况下由BeanWrapperImpl注册,但是可以通过将其自定义实例注册为自定义编辑器来覆盖。

CustomCollectionEditor

集合属性编辑器,可将任何源集合转换为给定的目标集合类型。

CustomDateEditor

Date自定义属性编辑器,支持自定义DateFormat。

CustomNumberEditor

Number自定义属性编辑器。可用于任何Number子类,如Integer,Long,Float,Double。默认情况下由BeanWrapperImpl注册,但是可以通过将其自定义实例注册为自定义编辑器来覆盖。

FileEditor

将字符串解析为java.io.File对象。默认情况下由BeanWrapperImpl注册。

InputStreamEditor

单向属性编辑器,根据文本字符串生成(通过中间的ResourceEditor和Resource)InputStream,因此InputStream属性可以直接设置为Strings。默认情况下由BeanWrapperImpl注册。请注意,默认用法不会关闭InputStream!

LocaleEditor

将字符串解析为Locale对象,反之亦然(String格式为[country] [variant],与Locale的toString()方法提供的功能相同)。默认情况下由BeanWrapperImpl注册。

PatternEditor

将字符串解析为java.util.regex.Pattern对象,反之亦然。

PropertiesEditor

将字符串转换为Properties对象。默认情况下由BeanWrapperImpl注册。

StringTrimmerEditor

修剪字符串的属性编辑器。 允许将空字符串转换为Null值。

URLEditor

将URL的字符串表示形式解析为实际的URL对象。默认情况下由BeanWrapperImpl注册。

ResourceEditor

资源描述符属性编辑器,可将字符串转换为Resource属性。如:将file:C:/myfile.txt或classpath:myfile.txt转换为Resource属性。 该路径可能包含$ {...}占位符,将被解析为Environment属性,如$ {user.dir}。默认情况下,无法解析的占位符将被忽略。

Aware感知

如果在某个Bean里面想要使用Spring框架提供的功能,可以通过Aware接口来实现。通过实现 Aware 接口,Spring 可以在启动时,调用接口定义的方法,并将 Spring 底层的一些组件注入到自定义的 Bean 中。

描述

ApplicationContextAware

当ApplicationContext创建实现ApplicationContextAware接口的Bean实例时,将为该Bean实例提供对该ApplicationContext的引用。

ApplicationEventPublisherAware

为Bean实例提供对ApplicationEventPublisherAware的引用。

BeanFactoryAware

为Bean实例提供对BeanFactory的引用

BeanNameAware

获取Bean在BeanFactory中配置的名字

MessageSourceAware

为Bean实例提供对MessageSource的引用

EnvironmentAware

获得Environment支持,这样可以获取环境变量

ResourceLoaderAware

获得资源加载器以获得外部资源文件

代码示例

public class AwareBean implements ApplicationContextAware, BeanNameAware {
    @Override
    public void setBeanName(String name) {
        System.out.println("=====>" + name);
    }

    @Override
    public void setApplicationContext(ApplicationContext ctx)
            throws BeansException {
        System.out.println("=====>" + ctx.getBean("awareBean"));
    }
}

Xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<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 id="awareBean" class="xxx.xxx.aware.AwareBean"/>
</beans>

忽略自动装配

Spring在ConfigurableListableBeanFactory接口中提供了2个可以忽略自动装配的方法:

// 自动装配时忽略指定接口或类的依赖注入
void ignoreDependencyType(Class<?> type);

// 忽略接口实现类中存在依赖外部的Bean注入
void ignoreDependencyInterface(Class<?> ifc);

忽略自动装配的做法使得一些基础组件(如:ApplicationContext或BeanFactory)依赖在自动装配时被忽略,而由框架统一设置依赖。如ApplicationContextAware接口的设置会在ApplicationContextAwareProcessor类中完成。

示例公用xml文件

<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 class="ai.yunxi.TestBean" name="testB1;testB2"/>

    <bean id="human" class="ai.yunxi.autowired.Human"/>
    <bean id="humanService" class="xxx.xxx.autowired.HumanService" autowire="byName"/>
    <!-- 去掉下面的注释,则ignoreDependencyType生效 -->
    <!--<bean class="ai.yunxi.autowired.HumanAutowiringProcessor"/>-->

    <bean id="list" class="java.util.ArrayList">
        <constructor-arg>
            <list>
                <value>foo</value>
                <value>bar</value>
            </list>
        </constructor-arg>
    </bean>
    <bean id="ignoreImpl" class="xxx.xxx.autowired.IgnoreImpl" autowire="byName" />
    <!-- 去掉下面的注释,则ignoreDependencyInterface生效 -->
    <!--<bean class="xxx.xxx.autowired.InterfaceIgnoreProcessor"/>-->
</beans>

ignoreDependencyType

public class Human {
    private String name;

    public Human( String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

实现了BeanFactoryPostProcessor的忽略自动装配处理器,这里是忽略的类。

public class HumanAutowiringProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
            throws BeansException {
        
        beanFactory.ignoreDependencyType(Human.class);
    }
}

ignoreDependencyInterface

接口类

public interface IgnoreInterface {
    void setList(List<String> list);
}

实现类

public class IgnoreImpl implements IgnoreInterface {

    private List<String> list;

    @Override
    public void setList(List<String> list) {
        this.list = list;
        System.out.println("ok.......");
    }

    public List<String> getList() {
        return list;
    }
}

实现了BeanFactoryPostProcessor的忽略自动装配处理器,这里忽略的是接口。

public class InterfaceIgnoreProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
            throws BeansException {
        beanFactory.ignoreDependencyInterface(IgnoreInterface.class);
    }
}

BeanPostProcessor

如果想在Spring容器中完成Bean实例化、配置以及其他初始化方法前后要添加一些自己逻辑处理,就需要定义一个或多个BeanPostProcessor接口实现类,然后注册到Spring IoC容器中。

第四步 BeanFactory后处理

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // ServletContextAwareProcessor中拿到应用上下文持有的servletContext引用和servletConfig引用
    // 添加ServletContextAwareProcessor后处理器
    beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
    
    // 在自动注入时忽略指定的依赖接口
    beanFactory.ignoreDependencyInterface(ServletContextAware.class);
    beanFactory.ignoreDependencyInterface(ServletConfigAware.class);

    // 向WebApplicationContext使用的BeanFactory注册Web相关作用域对象
    WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
    
    // 注册和Environment有关的beans
    WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}

WebApplicationContextUtils

该类位于包org.springframework.web.context.support是一个使检索指定ServletContext的根WebApplicationContext的便捷工具类。它如下工具方法:

  1. 在Web容器启动过程中注册Web相关作用域Bean(request/session/globalSession/application)
  2. 在Web容器启动过程中注册相应类型的工厂Bean ,依赖注入的Bean时能访问到正确的对象(ServletRequest/ServletResponse/HttpSession/WebRequest)
  3. 在Web容器启动过程中注册Web相关环境Bean
  4. 在Web容器启动过程中初始化Servlet propertySources
  5. 在客户化Web视图或者MVC action中,使用该工具类可以很方便地在程序中访问Spring应用上下文(application context)。

自定义作用域

Scope也称作用域,在Soring Ioc容器指其创建的Bean对象对其他Bean对象的请求可见范围,是用来声明IoC容器中的对象应该处的限定场景或者说该对象的存活空间,即在IOC容器在对象进入相应的Scope之前,生成并装配这些对象,在该对象不再处于这些scope的限定之后,容器通常会销毁这些对象。

诸如WebApplicationContext之类的ApplicationContext可以注册相对于标准作用域(Singleton/Prototype)的特定环境Scope作用域,例如:“request”和“session”作用域。

Bean的Scope作用域范围同样是可扩展的:即可以定义自己的范围,甚至重新定义现有范围,但不能覆盖内置的Singleton和Prototype范围。

// 从scope中根据名字返回对象
Object get(String name, ObjectFactory objectFactory);

// 从Scope中删除该对象
Object remove(String name);

// 注册的Scope被销毁或Scope中的指定对象被销毁时执行回调
void registerDestructionCallback(String name, Runnable destructionCallback);

// 获取Scope的会话标识符
String getConversationId(); 

ConfigurableBeanFactory接口中允许使用自定义的作用域范围扩展BeanFactory的标准作用域“ Singleton”和“ Prototype”,并为新的作用域范围进行注册。在编写好自定义Scope之后,需要让Spring容器识别新的Scope作用域。

代码方式注册

以下方法是在Spring容器中注册新Scope的主要方法,该方法在ConfigurableBeanFactory接口中定义:

// 第一个参数是与该Scope的全局唯一名称。在Spring容器中,此名称是Singleton和Prototype
// 第二个参数是希望注册和使用的自定义Scope实例
void registerScope(String scopeName, Scope scope);

如果已经写好了自己的自定义Scope实现,并且已经将其进行了注册:

Scope threadScope = new SimpleThreadScope();
beanFactory.registerScope("thread", threadScope);

然后就可以在配置文件中创建与自定义Scope规则对应的Bean定义:

<bean id="..." class="..." scope="thread"/>

配置方式注册

对于ApplicationContext来说,因为它可以自动识别并加载BeanFactoryPostProcessor,所以我们就可以直接在配置文件中,通过这个CustomScopeConfigurer注册来使新的Scope作用域范围生效

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                      http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
        <property name="scopes">
            <map>
                <entry key="customerScope" value="xxx.xxx.scope.CustomerScope"/>
            </map>
        </property>
    </bean>-->

    <bean id="human" class="xxx.xxx.autowired.Human" scope="customerScope">
        <!-- 让Bean符合自定义的作用域 -->
        <!--<aop:scoped-proxy/>-->
    </bean>
</beans>

测试类

public class TestScope {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext ctx =
                new ClassPathXmlApplicationContext("scope.xml");

        // 代码方式注册新的Scope作用域
        // ctx.getBeanFactory().registerScope("customerScope", new CustomerScope());

        System.out.println(ctx.getBeanFactory().getBeanDefinition("human").getScope());
        String scopes[] = ctx.getBeanFactory().getRegisteredScopeNames();
        for (String scope : scopes) {
            System.out.println(scope);
        }
    }
}

第五步 调用后处理器

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

    // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
    // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

BeanFactoryPostProcessor

BeanFactoryPostProcessor接口与BeanPostProcessor相似,但有一个主要区别:BeanFactoryPostProcessor用来操作Bean的配置元数据。也就是说,Spring IoC容器允许BeanFactoryPostProcessor读取配置元数据,并能在容器实例化任何Bean之前更改这些元数据。换句话说 :就是可以让我们随心所欲地修改BeanFactory内所有BeanDefinition定义数据。

**BeanDefinitionRegistryPostProcessor **是对标准BeanFactoryPostProcessor的扩展,允许在进行常规BeanFactoryPostProcessor检测之前注册其他Bean定义。特别是,BeanDefinitionRegistryPostProcessor注册的Bean定义又定义了BeanFactoryPostProcessor实例。

使用示例

Xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<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 id="car" class="xxx.xxx.processor.Car">
        <property name="name" value="benz"/>
    </bean>

    <bean id="carBeanFactoryPostProcessor1"
          class="xxx.xxx.processor.CarBeanFactoryPostProcessor1">
        <property name="order" value="0" />
    </bean>

    <bean id="carBeanFactoryPostProcessor2"
          class="xxx.xxx.processor.CarBeanFactoryPostProcessor2">
        <property name="order" value="1" />
    </bean>
</beans>

自定义BeanFactoryPostProcessor

// 1号后置处理器
public class CarBeanFactoryPostProcessor1 implements BeanFactoryPostProcessor, Ordered {
    int order;

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
            throws BeansException {
        System.out.println("=======> 执行CarBeanFactoryPostProcessor1");
        BeanDefinition bd = beanFactory.getBeanDefinition("car");
        bd.getPropertyValues().addPropertyValue("name", "bmw");
    }

    public void setOrder(int order) {
        this.order = order;
    }

    @Override
    public int getOrder() {
        return order;
    }
}

// 2号后置处理器
public class CarBeanFactoryPostProcessor2 implements BeanFactoryPostProcessor, Ordered {
    int order;

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
            throws BeansException {
        System.out.println("=======> 执行CarBeanFactoryPostProcessor2");
        BeanDefinition bd = beanFactory.getBeanDefinition("car");
        bd.getPropertyValues().addPropertyValue("color", "red");
    }

    public void setOrder(int order) {
        this.order = order;
    }

    @Override
    public int getOrder() {
        return order;
    }
}

// 实现BeanDefinitionRegistryPostProcessor接口的后处理器类
public class MobileBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println("=======> 执行MobileBeanFactoryPostProcessor_1");
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(Mobile.class);
        registry.registerBeanDefinition("mobile", beanDefinitionBuilder.getBeanDefinition());
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("=======> 执行MobileBeanFactoryPostProcessor_2");
        BeanDefinition bd = beanFactory.getBeanDefinition("mobile");
        bd.getPropertyValues().addPropertyValue("number", "123");
    }
}

可以在项目中配置多个BeanFactoryPostProcessor,同时通过设置Order属性来控制这些BeanFactoryPostProcessor的执行顺序,当然仅当BeanFactoryPostProcessor实现Ordered接口时,才可以设置此属性。

Spring排序接口

Spring框架中有很多实现了相同接口的类,那么这些实现类之间必定会有优先级的问题。Spring提供了Ordered接口来处理相同接口实现类的优先级问题。Ordered接口,顾名思义,就是用来排序的。

流程源码分析

源码流程

源码解析

public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

    // 临时缓存,用来记录已经调用过的BeanFactoryPostProcessor
    Set<String> processedBeans = new HashSet<String>();

    // 如果BeanFactory实现了BeanDefinitionRegistry接口
    // 从类图上可以看到其实是指DefaultListableBeanFactory或者GenericApplicationContext
    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        // 存放普通BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
        // 存放BeanDefinitionRegistryPostProcessor
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();

        // 循环applicationContext中已经注册的BeanFactoryPostProcessor
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            // 如果是实现了BeanDefinitionRegistryPostProcessor的后处理器
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                    (BeanDefinitionRegistryPostProcessor) postProcessor;
                // 执行postProcessBeanDefinitionRegistry回调
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                // 把该后处理器加入到registryProcessors
                registryProcessors.add(registryProcessor);
            }
            else {
                // 否则就是普通的后处理器
                regularPostProcessors.add(postProcessor);
            }
        }

        // 在这里先不初始化FactoryBeans,因为需要保留这些Beans让BeanFactoryPostProcessor进行处理
        // BeanDefinitionRegistryPostProcessor将按照PriorityOrdered,Ordered进行分类
        
        // 临时缓存,用来记录待执行回调方法的BeanFactoryPostProcessor
        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();

        // 首先,处理实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor
        String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                // 保存到待执行BeanFactoryPostProcess回调的缓存
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                // 保存到已经执行过BeanFactoryPostProcess回调的缓存
                processedBeans.add(ppName);
            }
        }
        // 对待执行缓存进行排序
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        // 执行BeanFactoryPostProcess的回调函数
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        // 清空待执行BeanFactoryPostProcess回调的缓存
        currentRegistryProcessors.clear();

        // 其次,再处理实现了Ordered接口的BeanDefinitionRegistryPostProcessor
        Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                // 保存到待执行BeanFactoryPostProcess回调的缓存
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                // 保存到已经执行过BeanFactoryPostProcess回调的缓存
                processedBeans.add(ppName);
            }
        }
        // 对待执行缓存进行排序
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        // 执行BeanFactoryPostProcess的回调函数
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        // 清空待执行BeanFactoryPostProcess回调的缓存
        currentRegistryProcessors.clear();

        // 最后,处理所有其他BeanDefinitionRegistryPostProcessor
        boolean reiterate = true;
        // 循环处理其他BeanDefinitionRegistryPostProcessor
        while (reiterate) {
            reiterate = false;
            // 把所有实现BeanDefinitionRegistryPostProcessor的类名取出来
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            // 遍历postProcessorNames
            for (String ppName : postProcessorNames) {
                // 已经处理过的缓存不包含该类名
                if (!processedBeans.contains(ppName)) {
                    // 保存到待执行BeanFactoryPostProcess回调的缓存
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    // 保存到已经执行过BeanFactoryPostProcess回调的缓存
                    processedBeans.add(ppName);
                    reiterate = true;
                }
            }
            // 对待执行缓存进行排序
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            // 执行BeanFactoryPostProcess的回调函数
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // 清空待执行BeanFactoryPostProcess回调的缓存
            currentRegistryProcessors.clear();
        }

        // 处理所有处理器,并执行postProcessBeanFactory回调
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }
    else {
        // 调用在上下文中注册的工厂处理器
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }

    // 在这里不初始化FactoryBeans,因为需要让BeanFactoryPostProcessor来进行处理
    // 获取所有实现了BeanFactoryPostProcessor接口的类名称
    String[] postProcessorNames =
        beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

    // 实现了PriorityOrdered接口的PostProcessor缓存
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    // 实现了Ordered接口的PostProcessor缓存
    List<String> orderedPostProcessorNames = new ArrayList<String>();
    // 没有实现任何Order接口的PostProcessor缓存
    List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
    // 遍历postProcessorNames开始处理BeanFactoryPostProcessor
    for (String ppName : postProcessorNames) {
        if (processedBeans.contains(ppName)) {
            // 如果包含,代表在上面的代码已经处理过则跳过
        }
        // 首先,处理实现了PriorityOrdered接口的BeanFactoryPostProcessor
        else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        }
        // 其次,处理实现了Ordered接口的BeanFactoryPostProcessor
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        // 最后,处理没有实现任何Order接口接口的BeanFactoryPostProcessor
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // 首先,处理实现了PriorityOrdered接口的BeanFactoryPostProcessor
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    // // 其次,再处理实现了Ordered接口的BeanFactoryPostProcessor
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

    // // 最后,处理所有其他BeanFactoryPostProcessor
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

    // 清除被缓存的BeanDefinition,因为后处理器可能已经修改了原始元数据,例如:替换占位符
    beanFactory.clearMetadataCache();
}

第六步 注册后处理器

// 实例化并且注册所有BeanPostProcessors
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

BeanPostProcessor

BeanPostProcessor是Spring的Bean工厂中一个非常重要的接口,允许Spring框架在新创建Bean实例时对其进行定制化修改。比如我们对Bean内容进行修改、创建代理对象等等。也就是说,Spring IoC容器实例化了一个Bean,而后BeanPostProcessor开始完成它们的工作。

BeanPostProcessor接口定义了回调方法,可以实现这些方法,以提供自己的实例化逻辑(或覆盖容器的默认值),依赖关系解析逻辑等。如果您想在Spring容器完成Bean的实例化、配置和初始化之后实现一些自定义逻辑,则可以插入一个或多个自定义BeanPostProcessor实现。

public interface BeanPostProcessor {
    // Bean初始化之前调用
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
    
    // Bean初始化之后调用
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

在实际使用中可以配置多个BeanPostProcessor实例,并且可以通过设置Order属性来控制这些BeanPostProcessor的执行顺序。只有当BeanPostProcessor实现Ordered接口时,才可以设置此属性。

InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor实际上继承了BeanPostProcessor接口,主要作用于实例化阶段的前后。

使用方式

public class CarBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        System.out.println("===> 1.调用postProcessBeforeInitialization()");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        System.out.println("===> 1.调用postProcessAfterInitialization()");
        return bean;
    }
}

public class CarInstantiationBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
            throws BeansException {
        System.out.println("===> 2.调用postProcessBeforeInstantiation()");
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName)
            throws BeansException {
        System.out.println("===> 2.调用postProcessAfterInstantiation()");
        return false;
    }

    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
            throws BeansException {
        System.out.println("===> 2.调用postProcessPropertyValues()");
        return pvs;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        System.out.println("===> 2.调用postProcessBeforeInitialization()");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        System.out.println("===> 2.调用postProcessAfterInitialization()");
        return bean;
    }
}

Xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<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 id="car" class="xxx.xxx.processor.Car">
        <property name="name" value="benz"/>
    </bean>

    <bean id="testPostProcessor"
          class="xxx.xxx.processor.CarBeanPostProcessor"/>

    <bean id="testInstantiationBeanPostProcessor"
          class="xxx.xxx.processor.CarInstantiationBeanPostProcessor"/>
</beans>

源码解读

public static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

    // 从BeanFactory中获取所有BeanPostProcessor的名字
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    // 注册BeanPostProcessorChecker,以便在BeanPostProcessor实例化期间创建一个Bean时记录一条info消息
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

    // 对BeanPostProcessor按照实现的接口PriorityOrdered,Ordered进行分类并存储
    // 保存实现PriorityOrdered接口的BeanPostProcessor
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
    // 保存实现Ordered接口的BeanPostProcessor
    List<String> orderedPostProcessorNames = new ArrayList<String>();
    // 保存没有实现PriorityOrdered和Ordered接口的BeanPostProcessor
    List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
    // 遍历postProcessorNames所有的BeanPostProcessor
    for (String ppName : postProcessorNames) {
        // 如果调用适配函数,发现该类实现了PriorityOrdered接口
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            // 从容器中取出BeanPostProcessor
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            // 保存到List集合中
            priorityOrderedPostProcessors.add(pp);
            // 如果这个类实现了MergedBeanDefinitionPostProcessor接口
            if (pp instanceof MergedBeanDefinitionPostProcessor接口) {
                internalPostProcessors.add(pp);
            }
        }
        // 如果调用适配函数,发现该类实现了Ordered接口
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        // 既没有实现PriorityOrdered接口也没有实现Ordered接口
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // 首先,处理实现PriorityOrdered接口的BeanPostProcessor
    // 对BeanPostProcessor进行排序
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    // 注册BeanPostProcessor
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    // 其次,处理实现Ordered接口的BeanPostProcessor
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
    for (String ppName : orderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    // 对BeanPostProcessor进行排序
    sortPostProcessors(orderedPostProcessors, beanFactory);
    // 注册BeanPostProcessor
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    // 处理其他普通的BeanPostProcessor
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
    for (String ppName : nonOrderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    // 对BeanPostProcessor进行排序.
    sortPostProcessors(internalPostProcessors, beanFactory);
    // 注册BeanPostProcessor
    registerBeanPostProcessors(beanFactory, internalPostProcessors);

    // 重新注册后BeanPostProcessor,用于内部Bean检测为ApplicationListener,//将其移至处理器链的末尾(用于拾取代理等)
    // Re-register post-processor for detecting inner beans as ApplicationListeners,
    // moving it to the end of the processor chain (for picking up proxies etc).
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

Bean的类型

Spring中有两种类型的Bean:

  • 普通Bean

  • 工厂Bean(即:FactoryBean)

FactoryBean

普通Bean可以直接使用Xml进行配置,但如果你的Bean拥有复杂的初始化代码(如涉及到很多其他的Bean),使用XML配置方式比较困难,这时就可以使用FactoryBean,并在该类中编写复杂的初始化,然后将自定义FactoryBean插入容器。

FactoryBean接口提供了三种方法:

T getObject() throws Exception;   // 返回此工厂创建的对象实例
Class<?> getObjectType();         // 返回的对象类型,如果对象类型未知则返回null
boolean isSingleton();            // 如果FactoryBean返回单例返回true,否则返回false。

这个接口使你可以提供一个复杂的逻辑来生成Bean。它本质是一个Bean,但这个Bean不是用来注入到其它地方像Service、Dao一样使用的,它是用来生成其它Bean使用的。

Spring框架中的许多地方都使用了FactoryBean概念和接口,Spring附带了50多个FactoryBean接口实现。很多开源项目在集成Spring 时也都使用到FactoryBean,比如 MyBatis3 提供 mybatis-spring项目中的 org.mybatis.spring.SqlSessionFactoryBean。

FactoryBean使用示例:

PersonFactoryBean

public class PersonFactoryBean implements FactoryBean<Person> {

    private String jsonInfo;

    @Override
    public Person getObject() throws Exception {
        ObjectMapper om = new ObjectMapper();
        return om.readValue(jsonInfo, Person.class);
    }

    @Override
    public Class<?> getObjectType() {
        return Person.class;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }

    public String getJsonInfo() {
        return jsonInfo;
    }

    public void setJsonInfo(String jsonInfo) {
        this.jsonInfo = jsonInfo;
    }
}

beans.xml

<bean id="person" class="xxx.xxx.PersonFactoryBean">
    <property name="jsonInfo"
              value="{ &quot;id&quot;: 1,&quot;name&quot;: &quot;abc&quot;,
                     &quot;age&quot;: 27, &quot;salary&quot;: 5555.0,
                     &quot;address&quot;: &quot;beijing&quot;}"/>
</bean>

Bean生命周期

Spring Bean的生命周期只有四个阶段:

  1. 实例化(Instantiation):调用构造函数
  2. 属性赋值(Populate):设置依赖注入
  3. 初始化(Initialization):调用init方法
  4. 销毁(Destruction):调用destory方法

生命周期也可以理解为四个等级。每个等级中都用有相应的接口,实现其中某个接口或者将实现类注入到Spring容器,容器就会在相应的时机调用其方法。

  1. 工厂级处理器接口
  2. 容器级生命周期接口
  3. Bean级生命周期接口
  4. Bean本身方法

接口

**分类 **

描述

BeanFactoryPostProcessor

工厂后处理器接口

容器创建完毕,装配Bean源后立即调用

InstantiationAwareBeanPostProcessor

容器后处理器接口

分别在调用构造之前,注入属性之前,实例化完成时调用

BeanPostProcessor

容器后处理器接口

分别在Bean的初始化方法调用前后执行

BeanNameAware

Bean级后置处理器接口

注入属性后调用

BeanFactoryAware

Bean级后置处理器接口

注入属性后调用

InitializingBean

Bean级后置处理器接口

在类本身的初始化方法之前调用其方法(本身也是初始化方法)

DisposableBean

Bean级后置处理器接口

在类本身的销毁方法执行之前调用其方法(本身也是销毁方法)

init方法

Bean本身方法

在注入属性之后调用初始化方法

destroy方法

Bean本身方法

在关闭容器的时候进行销毁

Spring中Bean初始化/销毁的三种方法

  1. 通过实现 InitializingBean/DisposableBean 接口来定制初始化之后/销毁之前的操作方法;
  2. 在<bean> 元素上添加 init-method/destroy-method来指定初始化之后 /销毁之前调用的操作方法;
  3. 在方法上加上@PostConstruct 或@PreDestroy注解来指定该方法是在初始化之后还是销毁之前调用。
public class Person implements InitializingBean {
    private int id;
    private String name;
    private int age;
    private BigDecimal salary;
    private String address;

    public Person() {
        System.out.println("Person构造函数");
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public BigDecimal getSalary() {
        return salary;
    }

    public void setSalary(BigDecimal salary) {
        this.salary = salary;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @PostConstruct
    public void postConstruct(){
        System.out.println("调用PostConstruct");
    }

    public void initMethod(){
        System.out.println("调用initMethod");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("调用afterPropertiesSet()");
    }
}

Spring Bean的生命周期:

  1. Spring对Bean进行实例化,调用Bean的构造参数
  2. 设置对象属性,调用Bean的set方法,将属性注入到bean的属性中
  3. 检查Bean是否实现BeanNameAware、BeanFactoryAware、ApplicationContextAware接口,如果实现了这几个接口Spring会分别调用其中实现的方法。
  4. 如果Bean是否实现BeanPostProcessor接口,Spring会在初始化方法的前后分别调用postProcessBeforeInitialization和postProcessAfterInitialization方法
  5. 如果Bean是否实现InitalizingBean接口,将调用afterPropertiesSet()方法
  6. 如果Bean声明初始化方法,也会被调用
  7. 使用Bean。Bean将会一直保留在应用的上下文中,直到该应用上下文被销毁。
  8. 检查Bean是否实现DisposableBean接口,Spring会调用它们的destory方法
  9. 如果Bean声明销毁方法,该方法也会被调用

Bean获取

org.springframework.beans.factory.support.AbstractBeanFactory

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

    // 将别名解析为规范Bean名称,如果是FactoryBean还需删除前缀
    final String beanName = transformedBeanName(name);
    Object bean;

    // 检查缓存是否有对象
    // 循环依赖解决的关键入口
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        if (logger.isDebugEnabled()) {
            // 该Bean是否正在创建中
            if (isSingletonCurrentlyInCreation(beanName)) {
                // logger.debug(.....) 打印日志(略)
            }
            else {
                // logger.debug(.....) 打印日志(略)
            }
        }
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else {
        // 如果已经创建了Bean实例则抛出异常,因为可能在循环引用中
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // 检查工厂中是否存在Bean定义
        BeanFactory parentBeanFactory = getParentBeanFactory();
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // Not found -> check parent.
            String nameToLookup = originalBeanName(name);
            if (args != null) {
                // Delegation to parent with explicit args.
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else {
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
        }

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

        try {
            // 合并BeanDefinition。合并主要是因为BeanDefinition可能存在parent BeanDefinition
            // 所以要依据合并后的BeanDefinition来实例化和初始化
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            // 检查合并后的BeanDefinition。主要是检查是否是abstract
            checkMergedBeanDefinition(mbd, beanName, args);

            // 获取依赖信息
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                // 确保当前Bean依赖的Bean初始化
                for (String dep : dependsOn) {
                    if (isDependent(beanName, dep)) {
                        // throw异常(略)
                    }

                    try {
                        // 注册依赖Bean
                        registerDependentBean(dep, beanName);
                        // 获取依赖Bean
                        getBean(dep);
                    } catch (NoSuchBeanDefinitionException ex) {
                        // throw异常(略)
                    }
                }
            }

            // 创建Bean实例
            // 如果是单例对象
            if (mbd.isSingleton()) {
                // 使用匿名对象工厂来创建Bean
                sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                    @Override
                    public Object getObject() throws BeansException {
                        try {
                            // 创建Bean
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            // 从单例缓存中显式删除实例。在创建过程可能将它提前引用缓存中,以方便循环引用解析。
                            // 还要删除所有对该Bean临时引用的Bean
                            destroySingleton(beanName);
                            throw ex;
                        }
                    }
                });
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }
        // 如果是Prototype对象
            else if (mbd.isPrototype()) {
                // It's a prototype -> create a new instance.
                Object prototypeInstance = null;
                try {
                    // 记录到当前创建的原型对象缓存
                    beforePrototypeCreation(beanName);
                    // 创建Bean
                    prototypeInstance = createBean(beanName, mbd, args);
                }
                finally {
                    // 创建完毕,从当前创建的原型对象缓存移除
                    afterPrototypeCreation(beanName);
                }
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            }
            // 既不是Singleton也不是Prototype,可能是自定义scope的对象
            else {
                // 获取Scope名称
                String scopeName = mbd.getScope();
                // 根据名称解析出对应的Scope对象
                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, new ObjectFactory<Object>() {
                        @Override
                        public Object getObject() throws BeansException {
                            // 记录到当前创建的原型对象缓存
                            beforePrototypeCreation(beanName);
                            try {
                                // 创建Bean
                                return createBean(beanName, mbd, args);
                            }
                            finally {
                                // 创建完毕,从当前创建的原型对象缓存移除
                                afterPrototypeCreation(beanName);
                            }
                        }
                    });
                    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                }
                catch (IllegalStateException ex) {
                    // throw异常(略)
                }
            }
        }
        catch (BeansException ex) {
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
    }

    // 所需的类型与实际Bean实例类型进行匹配转换
    if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
        try {
            // 转换成需要的类型
            return getTypeConverter().convertIfNecessary(bean, requiredType);
        }
        catch (TypeMismatchException ex) {
            if (logger.isDebugEnabled()) {
                logger.debug("Failed to convert bean '" + name + "' to required type '" +
                             ClassUtils.getQualifiedName(requiredType) + "'", ex);
            }
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    }
    return (T) bean;
}

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry

// 根据Bean注册名称返回单例对象,检查已经实例化的单例,并允许提前曝光当前创建的单例对象(解析循环引用)
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        synchronized (this.singletonObjects) {
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null && allowEarlyReference) {
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    singletonObject = singletonFactory.getObject();
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return (singletonObject != NULL_OBJECT ? singletonObject : null);
}

// 根据Bean注册名称返回单例对象。如果尚未注册,则创建并注册一个新的
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(beanName, "'beanName' must not be null");
    // 注意synchronized
    synchronized (this.singletonObjects) {
        // 根据Bean名称从单例缓存中获取实例
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null) {
            if (this.singletonsCurrentlyInDestruction) {
                // 抛出异常。原因:工厂单例销毁时不允许创建Bean实例
                // throw new BeanCreationNotAllowedException(.......);
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
            }
            // 创建前检查,主要检查两项。如果不成功抛出异常
            // 1. 正在创建缓存inCreationCheckExclusions中不包含该Bean
            // 2. 待创建缓存singletonsCurrentlyInCreation中可以添加该Bean
            beforeSingletonCreation(beanName);
            boolean newSingleton = false;
            boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
            if (recordSuppressedExceptions) {
                this.suppressedExceptions = new LinkedHashSet<Exception>();
            }
            try {
                // 从工厂中获取单例对象
                singletonObject = singletonFactory.getObject();
                // 创建成功则为true
                newSingleton = true;
            }
            catch (IllegalStateException ex) {
                // 如果出现异常,则从单例缓存中获取
                singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                    throw ex;
                }
            }
            catch (BeanCreationException ex) {
                if (recordSuppressedExceptions) {
                    for (Exception suppressedException : this.suppressedExceptions) {
                        ex.addRelatedCause(suppressedException);
                    }
                }
                throw ex;
            }
            finally {
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = null;
                }
                // 创建后检查,仍然是两项检查:
                // 1. 正在创建缓存inCreationCheckExclusions中不包含该Bean
                // 2. 待创建缓存singletonsCurrentlyInCreation中可以移除该Bean
                afterSingletonCreation(beanName);
            }
            // 创建成功同步几个重要的缓存
            if (newSingleton) {
                // 同步缓存:
                // 1. singletonObjects中添加单例对象
                // 2. singletonFactories移除该Bean
                // 3. earlySingletonObjects移除该Bean
                // 4. registeredSingletons添加该BeanName
                addSingleton(beanName, singletonObject);
            }
        }
        return (singletonObject != NULL_OBJECT ? singletonObject : null);
    }
}

Bean创建

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory

// 创建实例,填充实例,应用后处理器
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
    if (logger.isDebugEnabled()) {
        logger.debug("Creating instance of bean '" + beanName + "'");
    }
    // 合并的BeanDefinition
    RootBeanDefinition mbdToUse = mbd;

    // 确保解析并加载Bean的Class
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    // 如果解析的类在合并的BeanDefinition不存在,则克隆Bean定义
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        // 设置Bean的Class
        mbdToUse.setBeanClass(resolvedClass);
    }

    try {
        // Spring将lookup-method和replace-method统称为override method,这里主要就是处理这2个函数
        mbdToUse.prepareMethodOverrides();
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                                               beanName, "Validation of method overrides failed", ex);
    }

    try {
        // 该函数的作用是给 BeanPostProcessors 后置处理器返回一个代理对象的机会
        // 这里是实现AOP处理的重要地方
        // AOP是通过BeanPostProcessor机制实现的,而接口InstantiationAwareBeanPostProcessor是实现代理的重点
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }
    catch (Throwable ex) {
        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                                        "BeanPostProcessor before instantiation of bean failed", ex);
    }

    // 如果后处理器返回的Bean为空,则调用doCreateBean执行创建Bean的过程
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    if (logger.isDebugEnabled()) {
        logger.debug("Finished creating instance of bean '" + beanName + "'");
    }
    return beanInstance;
}

// 实际创建指定的Bean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
            throws BeanCreationException {

    // BeanWrapper 是一个用于包装Bean实例的接口,通过这个接口可以设置/获取Bean实例的属性
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        // 从未完成的实例缓存中获取
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    // 如果缓存中不存在,则执行创建(三种方式)
    if (instanceWrapper == null) {
        // 创建 bean 实例,并将实例封装在BeanWrapper中返回。createBeanInstance中包含三种创建方式:
        // 1.工厂方法创建Bean实例
        // 2.通过构造方法自动注入(autowire by constructor)的方式创建
        // 3.通过无参构造方法方法创建
        // 如果Bean配置了lookup-method和replace-method,则使用CGLIB增强Bean实例
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    // 获取包装的Bean实例
    final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
    // 获取包装的Class
    Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
    // 待解析的目标类型
    mbd.resolvedTargetType = beanType;

    // 允许BeanPostProcessor修改合并的BeanDefinition。这里主要是合并Bean的定义信息
    // Autowired等注解就是在这一步完成预解析,并且将注解需要的信息放入缓存
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                // 应用MergedBeanDefinitionPostProcessor后处理器
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            }
            catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                                "Post-processing of merged bean definition failed", ex);
            }
            mbd.postProcessed = true;
        }
    }

    // earlySingletonExposure 是一个重要的变量,用于表示是否提前暴露单例Bean,用于解决循环依赖。
    // earlySingletonExposure 由三个条件组成:是否是单例、是否允许循环引用、当前Bean是否处于创建的状态中
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                                      isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        if (logger.isDebugEnabled()) {
            logger.debug("Eagerly caching bean '" + beanName +
                         "' to allow for resolving potential circular references");
        }
        // 避免循环依赖,在Bean初始化完成前添加ObjectFactory到singletonFactories缓存。
        addSingletonFactory(beanName, new ObjectFactory<Object>() {
            @Override
            public Object getObject() throws BeansException {
                // 此回调使后处理器有机会提前曝光Bean(即在目标Bean完全初始化之前)。通常是为了解决循环依赖
                return getEarlyBeanReference(beanName, mbd, bean);
            }
        });
    }

    // 下面是初始化Bean的流程
    Object exposedObject = bean;
    try {
        // 使用BeanDefinintion的属性值填充Bean实例
        populateBean(beanName, mbd, instanceWrapper);
        if (exposedObject != null) {
            // 初始化Bean
            // 如果Bean实现了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware接口则设置
            // 应用BeanPostProcessor后处理器
            // 执行自定义init-method方法
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }
    }
    catch (Throwable ex) {
        if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
            throw (BeanCreationException) ex;
        }
        else {
            throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
        }
    }

    if (earlySingletonExposure) {
        // 从提前曝光的Bean缓存中查询,目的是验证是否存在循环依赖
    // 如果存在循环依赖,在这里earlySingletonReference不为空
        Object earlySingletonReference = getSingleton(beanName, false);
        // 在检测到循环依赖的情况下,earlySingletonReference不会为null
        if (earlySingletonReference != null) {
            // 如果exposedObject没有在initializeBean初始化方法中被改变,说明没有被增强
            // 初始化之后的Bean等于原始的bean说明不是proxy对象
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            }
            else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                // 确定是否已经给指定的beanName称注册了依赖
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                }
                // Bean创建后其依赖的Bean一定也是已经创建的
                // 如果actualDependentBeans不为空,则表示依赖的Bean并没有被创建完,即存在循环依赖
                if (!actualDependentBeans.isEmpty()) {
                    // 抛出异常
                    // throw new BeanCurrentlyInCreationException(....)
                }
            }
        }    }

    // Register bean as disposable.
    // 如果Bean实现了Disposable,则注册该Bean为
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}

// 创建Bean实例
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
    // Make sure bean class is actually resolved at this point.
    Class<?> beanClass = resolveBeanClass(mbd, beanName);

    if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
        // 抛出异常
        // throw new BeanCreationException(.....);
    }

    // 如果工厂方法不为空
    if (mbd.getFactoryMethodName() != null) {
        // 使用工厂方法创建实例
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // Shortcut when re-creating the same bean...
    boolean resolved = false;
    boolean autowireNecessary = false;
    if (args == null) {
        synchronized (mbd.constructorArgumentLock) {
            if (mbd.resolvedConstructorOrFactoryMethod != null) {
                resolved = true;
                autowireNecessary = mbd.constructorArgumentsResolved;
            }
        }
    }
    if (resolved) {
        if (autowireNecessary) {
            return autowireConstructor(beanName, mbd, null, null);
        }
        else {
            return instantiateBean(beanName, mbd);
        }
    }

    // Candidate constructors for autowiring?
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        return autowireConstructor(beanName, mbd, ctors, args);
    }

    // 调用实例化策略接口来实例化Bean,这里使用无参构造
    return instantiateBean(beanName, mbd);
}

// 实例化Bean
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
    try {
        Object beanInstance;
        final BeanFactory parent = this;
        if (System.getSecurityManager() != null) {
            beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
                @Override
                public Object run() {
                    return getInstantiationStrategy().instantiate(mbd, beanName, parent);
                }
            }, getAccessControlContext());
        }
        else {
            // InstantiationStrategy负责进行实例化
            // SimpleInstantiationStrategy是一个简单的用于Bean实例化的类。如:由Bean类的默认构造函数、带参构造函数或者工厂方法等来实例化Bean。不支持方法注入。
            // CglibSubclassingInstantiationStrategy如果方法需要被覆盖来实现“方法注入”,使用CGLIB动态生成子类
            beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
        }
        // 实例化后的Bean使用BeanWrapper包装。BeanWrapper可以设置以及访问被包装对象的属性值
        BeanWrapper bw = new BeanWrapperImpl(beanInstance);
        // 初始化BeanWrapper包装包含了2个工作:设置ConversionService和CustomerEditor
        initBeanWrapper(bw);
        return bw;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
    }
}

// 初始化Bean
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged(new PrivilegedAction<Object>() {
            @Override
            public Object run() {
                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;
}

解决循环引用

// 注册名称返回单例对象,检查已经实例化的单例,并允许提前引用当前创建的单例对象(解析循环引用)
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 从单例缓存中根据Bean名字获取单例对象
    Object singletonObject = this.singletonObjects.get(beanName);
    // 如果单例对象为空,并且单例对象正在创建中
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        // 注意synchronized关键字
        synchronized (this.singletonObjects) {
            // 从earlySingletonObjects缓存中通过Bean名称获取对象
            singletonObject = this.earlySingletonObjects.get(beanName);
            // 如果单例对象仍然为空,并且允许提前引用为true
            // allowEarlyReference参数含义:是否允许提前曝光
            if (singletonObject == null && allowEarlyReference) {
                // 从singletonFactories中根据Bean名称获取对应的单例工厂
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    // 通过工厂创建单例对象(此时还未进行依赖注入)
                    singletonObject = singletonFactory.getObject();
                    // 把创建的单例对象放到提前引用的缓存
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    // 移除该单例对象的工厂
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
}

代码中出现的缓存:

  1. singletonObjects:初始化完成的单例对象缓存;
  2. earlySingletonObjects:提前曝光的单例对象缓存;
  3. singletonFactories:单例Bean的工厂函数对象缓存;
  4. singletonsCurrentlyInCreation:即将创建的单例集合

第七步 初始化消息源

Spring中定义一个MessageSource接口,以用于支持信息的国际化和包含参数的信息的替换。ApplicationContext接口扩展了MessageSource接口,因而提供了消息处理的功能(i18n或者国际化)。与HierarchicalMessageSource一起使用,还能够处理嵌套的消息,这些是Spring提供的处理消息的基本接口。

public interface MessageSource {
    // 用来从MessageSource获取消息的基本方法。如果在指定的locale中没有找到消息,则使用默认的消息
    // args中的参数将使用标准类库中的MessageFormat来替换消息中的值
    String getMessage(String code, Object[] args, String default, Locale loc):

    // 与上一个方法相同,不同之处在于:没有指定默认值。如果没找到消息,会抛出一个NoSuchMessageException异常。
    String getMessage(String code, Object[] args, Locale loc) throws NoSuchMessageException;

    // 与上面的方法不同之处在于:将code、args等属性封装到MessageSourceResolvable中
    String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
}

MessageSource类图

Spring提供了两个MessageSource实现:ResourceBundleMessageSource和StaticMessageSource。它们都继承HierarchicalMessageSource能够处理嵌套的消息。

ResourceBundleMessageSource会用得更多一些。StaticMessageSource很少被使用,但能以编程的方式向源添加消息。

类或接口

描述

HierarchicalMessageSource

MessageSource子接口,提供解析层级消息的能力。该接口的目的是设置父MessageSource用于当前对象无法解析消息时,由父MessageSource尝试解析。

DelegatingMessageSource

空的MessageSource,它将所有处理转发给父MessageSource。如果没有父MessageSource,它不会处理任何消息。用户未指定MessageSource时,Spring默认使用该类。该类的功能比较简单:将字符串和参数数组格式化为一个消息字符串

AbstractMessageSource

支持“配置文件”方式的抽象类,内部提供一个与区域设置无关的公共消息配置文件,消息代码为关键字

AbstractResourceBasedMessageSource

基于资源并实现了MessageSource接口的抽象类,同时提供了一些参数配置的方法

ResourceBundleMessageSource

该类通过beanName指定一个资源名(包括类路径的全限定资源名),或通过beanNames指定一组资源名。不同的区域获取加载资源文件,达到国际化信息的目的。该类依赖JDK的ResourceBundle,并结合了JDK MessageFormat提供的标准消息解析。被访问的ResourceBundle和为每个消息生成的MessageFormat都会被缓存。

ReloadableResourceBundleMessageSource

同ResourceBundleMessageSource。该类参与Spring ApplicationContex的资源加载。它使用java.util.Properties作为其消息的自定义数据结构,通过PropertiesPersister策略从Spring Resource中加载它们。该策略不仅能够根据时间戳的更改重新加载文件,而且还能够使用特定的字符编码加载属性文件。

StaticMessageSource

MessageSource的简单实现,允许以编程方式注册消息,提供基本的国际化支持(通常用于测试)

使用示例

Xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<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 id="messageSource"
          class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basenames">
            <list>
                <value>locale.messages</value>
                <value>locale.exceptions</value>
            </list>
        </property>
    </bean>
​
</beans>

messageSource配置

# exceptions_en_US.properties文件
exceptions.illegal = The user {0} attempted to login, time: {1}
​
# exceptions_zh_CN.properties文件
exceptions.illegal = \u975e\u6cd5\u7528\u6237{0}\u5c1d\u8bd5\u767b\u5f55, \u65f6\u95f4\uff1a{1}
​
# message_en_US.properties文件
id.ilegal = userid {0} is illegal! time: {1}
password.empty = username{0}'s password is empty!
​
# message_zh_CN.properties文件
id.ilegal = \u7528\u6237\u7f16\u53f7{0}\u975e\u6cd5\u767b\u5f55\uff01{1}
password.empty = \u7528\u6237\u540d{0}\u7684\u5bc6\u7801\u4e0d\u80fd\u4e3a\u7a7a\uff01

注意:中文messageSource文件需要把中文转为Ascii

源码解读

getMessage()时序图

该段源码主要目的

当一个ApplicationContext被加载时,它会自动在context中查找已定义为MessageSource类型的Bean。此Bean的名称须为messageSource。

如果找到,那么所有对上述方法的调用将被委托给该Bean。否则ApplicationContext会在其父类中查找是否含有同名的Bean。如果有,就把它作为MessageSource。如果最终没有找到任何的消息源,实例化一个空的DelegatingMessageSource,使它能够接受上述方法的调用。

protected void initMessageSource() {
    // 获取BeanFactory
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();

    // beanFactory中是否包含名字为messageSource的Bean
    if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
        // 创建MessageSource类型的Bean
        this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
        // 判断messageSource是否有parent MessageSource
        if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
            // 设置MessageSource的parent MessageSource.
            HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
            if (hms.getParentMessageSource() == null) {
                // 如果未注册任何父MessageSource,则仅将父上下文的MessageSource设置为父MessageSource
                hms.setParentMessageSource(getInternalParentMessageSource());
            }
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Using MessageSource [" + this.messageSource + "]");
        }
    }
    // beanFactory中不包含名字为messageSource的Bean
    else {
        // 新建DelegatingMessageSource对象
        DelegatingMessageSource dms = new DelegatingMessageSource();
        // 设置DelegatingMessageSource的parent MessageSource
        dms.setParentMessageSource(getInternalParentMessageSource());
        this.messageSource = dms;
        // 向BeanFactory中注册MessageSource
        beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
                         "': using default [" + this.messageSource + "]");
        }
    }
}

第八步 初始化事件广播

protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    // 检查配置中是否有applicationEventMulticaster的Bean定义
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        // 如果有则获取(实例化Bean)
        this.applicationEventMulticaster =
            beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
        if (logger.isDebugEnabled()) {
            logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
        }
    }
    else {
        // 如果没有手动创建SimpleApplicationEventMulticaster的实例
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        // 把创建的SimpleApplicationEventMulticaster注册到BeanFactory
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
                         APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                         "': using default [" + this.applicationEventMulticaster + "]");
        }
    }
}

ApplicationContext中的事件处理是通过ApplicationEvent抽象类和ApplicationListener接口实现的。将实现ApplicationListener接口的Bean部署到上下文中,那么每次将ApplicationEvent发布到ApplicationContext时,该Bean都会得到通知。本质上,这是标准的观察者设计模式。

观察者模式

  • Subject:抽象主题类。保存对所有观察者对象的引用,每个主题都可以有任意数量的观察者。该接口可以添加和删除观察者对象
  • ConcreteSubject:具体主题。将状态保存到具体观察者对。在主题内部发生改变时,给所有登记的观察者发出通知。
  • Observer:抽象观察者。为所有具体的观察者定义接口,在得到主题通知时更新自己。
  • ConcreteObserver:具体观察者。实现更新接口,以使自身状态和主题状态同步。

具体实现

抽象被观察者接口

public interface Subject {
    // 添加观察者
    public void addObserver(Observer o);
    // 删除观察者
    public void removeObserver(Observer o);
    // 通知观察者
    public void notifyObserver();
}

抽象观察者接口

public interface Observer {
    // 当被观察者调用notify()方法时,观察者的update()方法会被回调
    public void update(String message);
}

定义被观察者,实现了Observerable接口,对Observerable接口的三个方法进行了具体实现,同时有一个List集合,用以保存注册的观察者,等需要通知观察者时,遍历该集合即可。

/**
 * 被观察者
 * 实现了Subject接口,对Subject接口的三个方法进行了具体实现
 */
public class ConcreteSubject implements Subject {
    
    // 保存观察者的集合
    private List<Observer> list;
    private String message;
    
    public ConcreteSubject() {
        list = new ArrayList<Observer>();
    }
    
    @Override
    public void addObserver(Observer o) {
        list.add(o);
    }
    
    @Override
    public void removeObserver(Observer o) {
        if(!list.isEmpty())
            list.remove(o);
    }

    //遍历
    @Override
    public void notifyObserver() {
        for(int i = 0; i < list.size(); i++) {
            Observer oserver = list.get(i);
            oserver.update(message);
        }
    }
    
    public void setMessage(String s) {
        this.message = s;
        System.out.println("服务消息: " + s);
        //消息更新,通知所有观察者
        notifyObserver();
    }
}

具体观察者

public class User implements Observer {

    private String name;
    private String message;
    
    public User(String name) {
        this.name = name;
    }
    
    @Override
    // 实现update方法
    public void update(String message) {
        this.message = message;
        read();
    }

    public void read() {
        System.out.println(name + " 收到推送消息: " + message);
    }
}

测试类

public class Test {
    public static void main(String[] args) {
        ConcreteSubject cs = new ConcreteSubject();

        Observer user1 = new User("Zhangsan");
        Observer user2 = new User("Lisi");
        Observer user3 = new User("Wangwu");

        cs.addObserver(user1);
        cs.addObserver(user2);
        cs.addObserver(user3);
        cs.setMessage("发布了消息1");

        System.out.println("----------------------------------------------");
        cs.removeObserver(userZhang);
        cs.setMessage("发布了消息2");
    }
}

事件驱动机制

事件驱动的常见形式便是发布-订阅模式。

在跨进程的通信间,我们通常采用引入 MQ (消息队列) 来实现消息的发布和订阅。目前主流应用的架构中,均采用消息的发布-订阅模式来进行大型分布式系统的解耦。使得数据生产方和使用方分离,同时 MQ 还可起到削峰等作用。

同一进程内很多时候也需要这种事件驱动机制来进行逻辑解耦。

事件机制主要由三个部分组成:

  • 事件对象:事件实体。封装事件源对象和事件,在事件源和监听器之间传递信息

  • 监听器:监听事件对象。事件发生时处理回调

  • 事件源:事件发生的起源。注册监听,对事件进行响应。

Java的事件机制

Java 提供了事件相关的接口定义:

  • 事件对象:EventObject 自定义事件对象需要继承该类

  • 监听器:EventListener 事件监听器接口

  • 事件源:不需要实现任何接口,Java 中也没给出相应的定义

示例

事件对象

public class JDKEventObject extends EventObject {

    private Object source;

    /**
     * Constructs a prototypical Event.
     *
     * @param source The object on which the Event initially occurred.
     * @throws IllegalArgumentException if source is null.
     */
    public JDKEventObject(JDKEventSource source) {
        super(source);
        this.source = source;
    }

    @Override
    public Object getSource() {
        return source;
    }
}

监听器

public interface JDKEventListener extends EventListener {
    public void handleEvent(JDKEventObject event);
}

事件源

public class JDKEventSource {
    private Set<EventListener> listeners = new HashSet();

    private String message;

    public void addListener(EventListener event) {
        listeners.add(event);
    }

    public void removeListener(EventListener event) {
        if (listeners.contains(event))
            listeners.remove(event);
    }

    public void fireEvent() {
        Iterator<EventListener> iter = listeners.iterator();
        while (iter.hasNext()) {
            JDKEventListener listener = (JDKEventListener) iter.next();
            listener.handleEvent(new JDKEventObject(this));
        }
    }
}

测试类

public class JDKEventTest {
    public static void main(String[] args) {
        JDKEventSource eventSource = new JDKEventSource();

        eventSource.addListener(new JDKEventListener() {
            @Override
            public void handleEvent(JDKEventObject event) {
                System.out.println("事件1......");
            }
        });
        eventSource.addListener(new JDKEventListener() {
            @Override
            public void handleEvent(JDKEventObject event) {
                System.out.println("事件2......");
            }
        });
        eventSource.fireEvent();
    }
}

事件处理机制在某种程度上与发布-订阅模式非常相似,事件监听器的角色与观察者类似,事件源则充当了被观察对象。事件源状态触发后,主动发起通知给监听器,监听器完成各种后续处理。

Spring事件机制

Spring内置事件:

事件类

说明

ContextRefreshedEvent

ApplicationContext初始化或刷新时触发该事件。通常在Spring加载或刷新应用上下文时,同事也想刷新预加载的资源,就可以通过监听ContextRefreshedEvent来做这样的事情。这里的“初始化”是指所有Bean均已加载,检测到并激活了BeanPostProcessors,已预先实例化单例并且可以使用ApplicationContext对象。只要上下文尚未关闭,选用的ApplicationContext支持这种“热”刷新(如:XmlWebApplicationContext支持热刷新,但GenericApplicationContext不支持),刷新可以被多次触发。

ContextStartedEvent

ApplicationContext启动时触发该事件。"Started" 意味着所有Lifecycle Bean会获得启动事件。 通常,此事件用于在显式停止后重新启动Bean时,也可以用于启动尚未配置为自动启动的组件。

ContextStoppedEvent

ApplicationContext被停止时触发该事件。"Stopped"是指所有Lifecycle Bean都收到一个明确的停止事件。已停止的上下文可以通过start()调用重新启动

ContextClosedEvent

ApplicationContext被关闭时触发该事件。 "Closed" 意味着容器管理的所有单例Bean都被销毁。关闭的上下文表示容器生命周期结束,它不能刷新或重新启动。

RequestHandledEvent

基于Web应用的事件,当一个HTTP请求完成后,触发该事件。该事件仅适用于使用DispatcherServlet的Web应用程序。

容器生命周期

BeanPostProcessor及Bean的初始和销毁回调这些事件都是建立在容器已经成功启动的基础上,如果我们想在容器本身的生命周期。

// 生命周期接口,任何Spring管理的对象都可以实现该接口
public interface Lifecycle {
    void start();
    void stop();
    boolean isRunning();
}

// 管理ApplicationContext生命周期
public interface LifecycleProcessor extends Lifecycle {
    void onRefresh();
    void onClose();
}

public interface SmartLifecycle extends Lifecycle, Phased {
    // Lifecycle Bean是否自动启动
    boolean isAutoStartup();

    // 停止的时候执行回调,默认超时时间30秒
    void stop(Runnable callback);
}

// Phased最小的对象首先启动,停止时,顺序和启动时相反
public interface Phased {
    // SmartLifecycle的实现类默认Phase为0
    int getPhase();
}

常规的Lifecycle接口只在容器上下文显式的调用start()/stop()方法时,才会去回调Lifecycle实现类的start/stop方法逻辑。并不意味着在上下文刷新时自动启动。

另外,LifeCycle Bean在销毁之前不能保证会收到停止通知。正常关闭时,所有Lifecycle Bean在销毁回调之前首先会收到停止通知,但是在上下文的生命周期内进行热刷新或中止刷新尝试时,只会调用destroy方法。

// 实现Lifecycle的测试类
public class TestLifeCycle implements Lifecycle {

    private boolean running = false;

    public TestLifeCycle() {
        System.out.println("TestLifeCycle.......");
    }

    @Override
    public void start() {
        System.out.println("TestLifeCycle.start().......");
        running = true;
    }

    @Override
    public void stop() {
        System.out.println("TestLifeCycle.start().......");
        running = false;
    }

    @Override
    public boolean isRunning() {
        return running;
    }
}

// 实现SmartLifecycle的测试类
public class TestSmartLifecycle implements SmartLifecycle {

    private boolean running = false;

    public TestSmartLifecycle() {
        System.out.println("TestSmartLifecycle.......");
    }

    @Override
    public boolean isAutoStartup() {
        return true;
    }

    @Override
    public int getPhase() {
        return 10000;
    }

    @Override
    public void start() {
        System.out.println("TestSmartLifecycle.start().......");
        running = true;
    }

    @Override
    public void stop() {
        System.out.println("TestSmartLifecycle.stop().......");
        running = false;
    }

    @Override
    public void stop(Runnable callback) {
        System.out.println("TestSmartLifecycle.stop(Runnable callback).......");
        running = false;
    }

    @Override
    public boolean isRunning() {
        return running;
    }
}

事件机制

Spring事件机制中除了事件对象和监听者者两个角色之外,“事件广播器”则负责把事件转发给监听者:

类名

描述

ApplicationEvent

Spring提供的事件类,继承自 EventObject 类

ApplicationListener

事件监听者,该类接收一个泛型,供 ApplicationEventPublisher 在发布事件时选择 EventListener

ApplicationEventPublisher

封装事件发布功能的接口,通知所有在 Spring 中注册的该事件的监听者进行处理

ApplicationEventPublisherAware

Spring 提供的 Aware 接口之一,实现该接口的 Bean 可以获取 ApplicationEventPublisher 并进行发布事件

ApplicationEventMulticaster

管理多个ApplicationListener对象并向其发布事件的接口

示例

Spring 中,不需要我们手动进行监听器注册。ApplicationListener 对象一旦在 Spring 容器中被注册,Spring 会进行监听器的注册,实现事件的监听。

服务类

// Spring容器检测到Service实现了ApplicationEventPublisherAware接口,会自动调用setApplicationEventPublisher
public class SpringService implements ApplicationEventPublisherAware {

    private List<String> nameList;
    private ApplicationEventPublisher publisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
        this.publisher = publisher;
    }

    public void setNameList(List<String> list) {
        this.nameList = list;
    }

    // 要发布自定义ApplicationEvent,需要在ApplicationEventPublisher上调用publishEvent方法
    public void sendMessage(String name) {
        if (nameList.contains(name)) {
            publisher.publishEvent(new SpringEvent(this, name));
            return;
        }
    }
}

监听器

// 要接收自定义的ApplicationEvent,需要实现ApplicationListener监听器
public class SpringListener implements ApplicationListener<SpringEvent> {

    String notifier;

    public void setNotifier(String notifier) {
        this.notifier = notifier;
    }

    @Override
    public void onApplicationEvent(SpringEvent event) {
        System.out.println("onApplicationEvent: "+ notifier);
    }
}

事件类

public class SpringEvent extends ApplicationEvent {

    String name;

    /**
     * Create a new ApplicationEvent.
     *
     * @param source the object on which the event initially occurred (never {@code null})
     */
    public SpringEvent(Object source, String name) {
        super(source);
        this.name = name;
    }
}

第九步 初始化主题

protected void onRefresh() throws BeansException {
    // For subclasses: do nothing by default.
}

SpringMVC框架主题可以设置应用程序的整体外观,从而增强用户体验。主题是静态资源的集合,通常有css样式表和图片构成,这些css样式和图片会直接影响应用程序的视觉样式。

要在Web应用中使用主题,必须实现ThemeSource接口,WebApplicationContext接口就扩展了ThemeSource,但将其职责委托给专用的实现。

默认委托将是ResourceBundleThemeSource,该实现从类路径的根加载主题属性文件。要使用自定义ThemeSource或需要配置ResourceBundleThemeSource的属性,可以在应用程序上下文中注册使用保留名称'themeSource'的Bean,Web应用程序上下文会自动检测到具有'themeSource'名称的Bean并使用它。

主题使用示例

SpringMVC配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <mvc:default-servlet-handler />
    <mvc:annotation-driven  />

    <context:component-scan base-package="xxx.xxx" />

    <!-- 视图解析 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <!-- Theme主题资源 -->
    <bean id="themeSource" class="org.springframework.ui.context.support.ResourceBundleThemeSource">
        <property name="basenamePrefix" value="theme." />
    </bean>

    <!-- Theme主题解析器 -->
    <bean id="themeResolver" class="org.springframework.web.servlet.theme.CookieThemeResolver">
        <property name="defaultThemeName" value="blue" />
    </bean>

    <!-- Theme主题拦截器 -->
    <mvc:interceptors>
        <bean id="themeInterceptor" class="org.springframework.web.servlet.theme.ThemeChangeInterceptor">
            <property name="paramName" value="theme" />
        </bean>
    </mvc:interceptors>
</beans>

主题资源文件

blue.properties和gray.properties两个属性配置文件存放到resources资源目录下面。

blue.properties

------------------------------
blue.properties
------------------------------
# css对应位置
styleSheet=/css/blue.css
# 图片对应位置
background=images/blue.png

gray.properties

------------------------------
gray.properties
------------------------------
# css对应位置
styleSheet=/css/gray.css
# 图片对应位置
background=images/gray.png

前端页面

JSP代码中引用主题文件的键。在JSP中,通常使用spring:theme标签来执行此操作,该标签与spring:message标签的使用方法非常相似。

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<html>
<head>
<link rel="stylesheet" href="<spring:theme code='styleSheet'/>" type="text/css"/>
<title>Title</title>
</head>
<body style="background: url(<spring:theme code='background'/>)">
<a href="?theme=blue">blue</a> - <a href="?theme=gray">gray</a>
</body>
</html>

源码解析

public static ThemeSource initThemeSource(ApplicationContext context) {
    // 判断容器中是否包含"themeSource"的Bean
    if (context.containsLocalBean(THEME_SOURCE_BEAN_NAME)) {
        // 如果包含则实例化这个themSource
        ThemeSource themeSource = context.getBean(THEME_SOURCE_BEAN_NAME, ThemeSource.class);
        // 设置themeSource的父themeSource
        if (context.getParent() instanceof ThemeSource && themeSource instanceof HierarchicalThemeSource) {
            // 用来表示层级关系的ThemeSource对象
            HierarchicalThemeSource hts = (HierarchicalThemeSource) themeSource;
            if (hts.getParentThemeSource() == null) {
                hts.setParentThemeSource((ThemeSource) context.getParent());
            }
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Using ThemeSource [" + themeSource + "]");
        }
        return themeSource;
    }
    else {
        // 如果context中不包含"themeSource"的定义
        HierarchicalThemeSource themeSource = null;
        // 如果context的parent是ThemeSource实例,则设置该contexnt的父ThemeSource
        if (context.getParent() instanceof ThemeSource) {
            // 实例化一个DelegatingThemeSource
            themeSource = new DelegatingThemeSource();
            themeSource.setParentThemeSource((ThemeSource) context.getParent());
        }
        else {
            // 否则,实例化一个ResourceBundleThemeSource
            themeSource = new ResourceBundleThemeSource();
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate ThemeSource with name '" + THEME_SOURCE_BEAN_NAME +
                         "': using default [" + themeSource + "]");
        }
        return themeSource;
    }
}

第十步 注册事件监听

protected void registerListeners() {
    // 注册静态指定的监听器
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }

    // 从BeanFactory中获取listener的名称,并注册
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }

    // 发布早期事件
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

事件广播类图

说明

ApplicationEventMulticaster

管理多个监听器并向其发布事件对象的接口

AbstractApplicationEventMulticaster

提供监听器注册/管理功能的抽象实现

SimpleApplicationEventMulticaster

将所有事件多播到所有已注册的监听器,让监听器忽略它们不感兴趣的事件。默认情况下,所有监听器在线程中被调用。

源码解读

public void addApplicationListener(ApplicationListener<?> listener) {
    synchronized (this.retrievalMutex) {
        Object singletonTarget = AopProxyUtils.getSingletonTarget(listener);
        // 如果代理的目标监听器也已经注册到多播器,为了避免两次都调用相同的监听器
        // 从多播器移除目标监听器
        if (singletonTarget instanceof ApplicationListener) {
            this.defaultRetriever.applicationListeners.remove(singletonTarget);
        }
        this.defaultRetriever.applicationListeners.add(listener);
        this.retrieverCache.clear();
    }
}

@Override
public void addApplicationListenerBean(String listenerBeanName) {
    synchronized (this.retrievalMutex) {
        this.defaultRetriever.applicationListenerBeans.add(listenerBeanName);
        this.retrieverCache.clear();
    }
}

// 获取喝Event匹配的事件类型,不匹配的排除在外
protected Collection<ApplicationListener<?>> getApplicationListeners(
            ApplicationEvent event, ResolvableType eventType) {
    // 获取事件源
    Object source = event.getSource();
    // 获取事件类型
    Class<?> sourceType = (source != null ? source.getClass() : null);
    // 使用事件源和事件类型构造缓存Key
    ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);

    // 在缓存中通过Key查找是否存在缓存
    ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
    if (retriever != null) {
        // 如果缓存中存在,则直接返回
        return retriever.getApplicationListeners();
    }

    // 通过类是否在classLoader或者parent classLoader中来判断类是否是可以缓存的
    if (this.beanClassLoader == null ||
        (ClassUtils.isCacheSafe(event.getClass(), this.beanClassLoader) &&
         (sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
        // 同步缓存
        synchronized (this.retrievalMutex) {
            // 通过Key获取缓存
            retriever = this.retrieverCache.get(cacheKey);
            if (retriever != null) {
                // 缓存不为空,则返回
                return retriever.getApplicationListeners();
            }
            // 构造ListenRetriever
            retriever = new ListenerRetriever(true);
            Collection<ApplicationListener<?>> listeners =
                retrieveApplicationListeners(eventType, sourceType, retriever);
            this.retrieverCache.put(cacheKey, retriever);
            return listeners;
        }
    }
    else {
        // 无ListenerRetriever缓存,不需要同步
        return retrieveApplicationListeners(eventType, sourceType, null);
    }
}

// 检索指定事件和源类型的监听器
private Collection<ApplicationListener<?>> retrieveApplicationListeners(
    ResolvableType eventType, Class<?> sourceType, ListenerRetriever retriever) {

    // List为要返回的监听器
    List<ApplicationListener<?>> allListeners = new ArrayList<ApplicationListener<?>>();

    Set<ApplicationListener<?>> listeners;
    Set<String> listenerBeans;
    synchronized (this.retrievalMutex) {
        // 使用成员变量defaultRetriever初始化listeners
        listeners = new LinkedHashSet<ApplicationListener<?>>(this.defaultRetriever.applicationListeners);
        // 使用成员变量defaultRetriever初始化listenerBeans
        listenerBeans = new LinkedHashSet<String>(this.defaultRetriever.applicationListenerBeans);
    }
    for (ApplicationListener<?> listener : listeners) {
        // 确定监听器是否支持指定的事件
        if (supportsEvent(listener, eventType, sourceType)) {
            if (retriever != null) {
                // 有缓存的情况(有传参决定)
                retriever.applicationListeners.add(listener);
            }
            allListeners.add(listener);
        }
    }
    if (!listenerBeans.isEmpty()) {
        BeanFactory beanFactory = getBeanFactory();
        for (String listenerBeanName : listenerBeans) {
            try {
                // BeanFactory中获取Class
                Class<?> listenerType = beanFactory.getType(listenerBeanName);
                
                if (listenerType == null || supportsEvent(listenerType, eventType)) {
                    // 从BeanFactory中获取listener
                    ApplicationListener<?> listener =
                        beanFactory.getBean(listenerBeanName, ApplicationListener.class);
                    // allListeners中不包含该监听器,并确定监听器是否支持指定的事件
                    if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
                        if (retriever != null) {
                            // 有缓存的情况(有传参决定)
                            retriever.applicationListenerBeans.add(listenerBeanName);
                        }
                        allListeners.add(listener);
                    }
                }
            }
            catch (NoSuchBeanDefinitionException ex) {
                // Singleton listener instance (without backing bean definition) disappeared -
                // probably in the middle of the destruction phase
            }
        }
    }
    // 对Listener进行排序
    AnnotationAwareOrderComparator.sort(allListeners);
    return allListeners;
}

第十一步 完成初始化

// 完成Context的BeanFactory初始化,并完成所有剩余的单例Bean的初始化
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // 为context上下文初始化conversion service
    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));
    }

    // 如果之前没有嵌入值解析器注册,则注册默认的嵌入值解析器
    // 所谓嵌入值解析器主要用于解析注解属性值
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
            @Override
            public String resolveStringValue(String strVal) {
                return getEnvironment().resolvePlaceholders(strVal);
            }
        });
    }

    // 初始化LoadTimeWeaverAware
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }

    // 停止使用TempClassLoader
    beanFactory.setTempClassLoader(null);

    // 冻结Bean定义配置(Bean定义不会被修改或进一步后处理),因为下一步会实例化对象
    beanFactory.freezeConfiguration();

    // 实例化所有剩余的单例对象(非懒加载的)
    beanFactory.preInstantiateSingletons();
}

源码解读

preInstantiateSingleton

// 确保所有非延迟初始化单例都被实例化
public void preInstantiateSingletons() throws BeansException {
    if (logger.isDebugEnabled()) {
        logger.debug("Pre-instantiating singletons in " + this);
    }

    // 遍历beanDefinitionNames副本以允许使用init方法注册新的BeanDefinition
    List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

    // Trigger initialization of all non-lazy singleton beans...
    // 触发所有非懒加载单例Bean的初始化
    for (String beanName : beanNames) {
        // 根据Bean的名称获取MergedBeanDefinition
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            // 判断该beanName是不是一个FactoryBean
            if (isFactoryBean(beanName)) {
                // 获取FactoryBean实例。通过FactoryBean的getBean方法可以获取FactoryBean创建的Bean实例
                final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                // 是否希望提前初始化
                boolean isEagerInit;
                if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                    isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                        @Override
                        public Boolean run() {
                            return ((SmartFactoryBean<?>) factory).isEagerInit();
                        }
                    }, getAccessControlContext());
                }
                else {
                    isEagerInit = (factory instanceof SmartFactoryBean &&
                                   ((SmartFactoryBean<?>) factory).isEagerInit());
                }
                if (isEagerInit) {
                    getBean(beanName);
                }
            }
            else {
                // 如果beanName对应的不是FactoryBean,则通过beanName获取Bean实例
                getBean(beanName);
            }
        }
    }

    // 触发所有实现SmartInitializingSingleton接口的Bean的初始化后回调
    for (String beanName : beanNames) {
        // 获取对应beanName的实例
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
            // 判断是否实现了SmartInitializingSingleton接口
            final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged(new PrivilegedAction<Object>() {
                    @Override
                    public Object run() {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }
                }, getAccessControlContext());
            }
            else {
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}

最后一步 完成刷新

protected void finishRefresh() {
    // 为上下文初始化生命周期处理器
    initLifecycleProcessor();

    // 将刷新事件传播到生命周期处理器
    getLifecycleProcessor().onRefresh();

    // 发布刷新完毕事件到对应的监听器
    publishEvent(new ContextRefreshedEvent(this));

    // 注册Mbean
    LiveBeansView.registerApplicationContext(this);
}

Spring使用BeanPostProcessor来处理可以找到的任何接口实现并调用具体的方法。如果需要自定义功能或其他生命周期行为,Spring并不提供现成的功能,需要自己实现BeanPostProcessor。

除了初始化和销毁回调外,Bean对象还可以实现Lifecycle接口,以便这些Bean可以在容器自身的生命周期驱动下进行start和stop过程。Lifecycle接口为具有生命周期要求的对象定义了基本方法。

当ApplicationContext接收到开始和停止信号时,它会调用那些关联到在该上下文中的所有Lifecycle实现类(如:启动和停止某些后台进程)。

解码解读

org.springframework.context.support.AbstractApplicationContext

// 初始化生命周期处理器
protected void initLifecycleProcessor() {
    // 获取BeanFactory
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    // 判断BeanFactory中是否已经定义过lifecycleProcessor
    if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
        // 如果定义过lifecycleProcessor,则使用beanFactory中的定义给lifecycleProcessor赋值
        this.lifecycleProcessor =
            beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
        if (logger.isDebugEnabled()) {
            // 日志打印
        }
    }
    else {
        // 如果BeanFactory中没有定义lifecycleProcessor,则构造一个DefaultLifecycleProcessor
        DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
        // 设置defaultProcessor的BeanFactory
        defaultProcessor.setBeanFactory(beanFactory);
        this.lifecycleProcessor = defaultProcessor;
        // 将defaultProcessor以单例的形式注册到BeanFactory的生命周期管理器
        beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate LifecycleProcessor with name '" +
                         LIFECYCLE_PROCESSOR_BEAN_NAME +
                         "': using default [" + this.lifecycleProcessor + "]");
        }
    }
}

org.springframework.context.support.DefaultLifecycleProcessor

private void startBeans(boolean autoStartupOnly) {
    // 获取所有的Lifecycle接口实现类
    Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
    // 按phase进行分组存储
    Map<Integer, LifecycleGroup> phases = new HashMap<Integer, LifecycleGroup>();
    for (Map.Entry<String, ? extends Lifecycle> entry : lifecycleBeans.entrySet()) {
        Lifecycle bean = entry.getValue();
        // 如果参数autoStartupOnly不等于true,或者bean是SmartLifecycle实现类并且autoStartup=true
        // autoStartupOnly=true  代表本次刷新为自动启动,触发所有自动启动的SmartLifecycle实现类
        // autoStartupOnly=false 代表本次刷新为显式调用,触发所有的Lifecycle实现类启动
        if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
            // 获取Lifecycle Bean的phase,phase默认为0
            int phase = getPhase(bean);
            // 根据phase获取对应的分组
            LifecycleGroup group = phases.get(phase);
            if (group == null) {
                // 如果没有分组,则新建一个分组
                group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
                // 把phase和对应的group放入到集合
                phases.put(phase, group);
            }
            // 把对应的Lifecycle Bean放到对应的分组中
            group.add(entry.getKey(), bean);
        }
    }
    // 遍历分组后的集合
    if (!phases.isEmpty()) {
        List<Integer> keys = new ArrayList<Integer>(phases.keySet());
        // 根据分组phase进行排序
        Collections.sort(keys);
        for (Integer key : keys) {
            // 根据分组顺序依次启动Lifecycle Bean
            phases.get(key).start();
        }
    }
}

// 遍历集合成员,执行Lifecycle实现类的start()函数回调
public void start() {
    if (this.members.isEmpty()) {
        return;
    }
    if (logger.isInfoEnabled()) {
        logger.info("Starting beans in phase " + this.phase);
    }
    // 对分组内的member进行排序
    Collections.sort(this.members);
    for (LifecycleGroupMember member : this.members) {
        if (this.lifecycleBeans.containsKey(member.name)) {
            // 启动Lifecycle Bean
            doStart(this.lifecycleBeans, member.name, this.autoStartupOnly);
        }
    }
}

private void doStart(Map<String, ? extends Lifecycle> lifecycleBeans, String beanName, boolean autoStartupOnly) {
    Lifecycle bean = lifecycleBeans.remove(beanName);
    if (bean != null && bean != this) {
        // 根据beanName获取相应的依赖Bean
        String[] dependenciesForBean = this.beanFactory.getDependenciesForBean(beanName);
        // 遍历依赖Bean
        for (String dependency : dependenciesForBean) {
            // 递归。先回调依赖Bean的start函数(如果依赖Bean是Lifecycle实现类)
            doStart(lifecycleBeans, dependency, autoStartupOnly);
        }

        if (!bean.isRunning() &&
            (!autoStartupOnly || !(bean instanceof SmartLifecycle) || ((SmartLifecycle) bean).isAutoStartup())) {
            if (logger.isDebugEnabled()) {
                // 打印日志
            }
            try {
                // 执行Lifecycle实现类的start()函数回调
                bean.start();
            }
            catch (Throwable ex) {
                throw new ApplicationContextException("Failed to start bean '" + beanName + "'", ex);
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Successfully started bean '" + beanName + "'");
            }
        }
    }
}
标签: spring

本文转载自: https://blog.csdn.net/qq_33259067/article/details/127098258
版权归原作者 Stevens Eason 所有, 如有侵权,请联系我们删除。

“Spring启动流程解析(总)”的评论:

还没有评论