SpringIOC容器设计


IOC简介

在Spring IoC容器的设计中,作者设计了两个接口来表示容器

  • BeanFactory
    BeanFactory简单粗暴,可以理解为HashMap,key是BeanName,value是Bean实例,通常只提供put和get。这系列容器只实现了容器的最基本功能,可看做为简单容器。

  • ApplicationContext
    ApplicationContext应用上下文,它作为容器的高级形态而存在。应用上下文在简单容器的基础上,增加了许多面向框架的特性,同时对应用环境做了许多适配。

Spring通过定义BeanDefinition来管理基于Spring的应用中的各种对象以及它们之间的相互依赖关系。对IoC容器来说,BeanDefinition就是依赖反转模式中管理的对象依赖关系的数据抽象,也是容器实现依赖反转功能的核心数据结构,依赖反转功能都是围绕这个BeanDefinition的处理来完成的。
IOC

两条设计主线

第一条

第一条接口设计的主线是从接口BeanFactoryHierarchicalBeanFactory再到ConfigurableBeanFactory,是一条主要的BeanFactory设计路径。在这条接口设计路径中,BeanFactory接口定义了基本的IOC容器的规范。在这个接口定义中.包括了getBean()这样的IOC容器的基本方法(通过这个方法可以从容器中取得Bean)。HierarchicalBeanFactory接口在继承了BeanFactory的基本接口之后,增加了getParentBeanFactory()的接口功能,使BeanFactory具备了双亲IOC容器的管理功能.在接下来的ConfigurableBeanFactory接口中,主要定义了一些对BeanFactory的配置功能,比如通过setParentBeanFactory()设置双亲IOC容器,通过addBeanPostProcessor()配置Bean后置处理器等等。通过这些接口设计的叠加,定义了BeanFactory就是简单IOC容器的基本功能。
ConfigurableBeanFactory

BeanFactory

package com.zqr.SpringDetail.org.springframework.beans.factory;

import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;

public interface BeanFactory {

    /**
     * 用&符号获取BeanFactory本身,用来区分通过容器获取FactoryBean产生的对象和FactoryBean本身.
     *     比如:myJndiObject是一个FactoryBean,使用&myJndiObject获取到的是FactoryBean,而不是myJndiObject产生的对象.
     * 
     *     Pass:
     *         BeanFactory与FactoryBean
     *             BeanFactory是一个Factory,用来管理Bean;
     *             FactoryBean是一个工厂Bean,能够产生和修饰对象生成.
     */
    String FACTORY_BEAN_PREFIX = "&";


    /**
    *    使用不同的Bean检索方法,从IoC容器中得到所需要的Bean,从而忽略具体的IoC实现.
    *这些检索方法代表的是最为基本的容器入口.
    */
    Object getBean(String name) throws BeansException;
    <T> T getBean(String name, Class<T> requiredType) throws BeansException;
    <T> T getBean(Class<T> requiredType) throws BeansException;
    Object getBean(String name, Object... args) throws BeansException;
    <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

    /**
     * 容器是否含有指定名字的Bean
     */
    boolean containsBean(String name);

    /**
     * 指定名字的Bean是否是Singleton类型.
     * Pass:对于Singleton属性,可以在BeanDefinition中指定.
     */
    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

    /**
     * 指定名字的Bean是否是Prototype类型.
     */
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

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

    /**
     * 查询指定名字的Bean的Class类型是否是特定的Class类型.
     */
    boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

    /**
     * 查询指定名字的Bean的Class类型.
     */
    Class<?> getType(String name) throws NoSuchBeanDefinitionException;

    /**
     * 查询指定名字的Bean的所有别名.这些别名都是用户在BeanDefinition中定义的.
     */
    String[] getAliases(String name);

}

HierarchicalBeanFactory

package org.springframework.beans.factory;

import org.springframework.lang.Nullable;
/**
 * 定义了对BeanFactory层次结构的操作
 */
public interface HierarchicalBeanFactory extends BeanFactory {

    /**
     * 返回本Bean工厂的父工厂
     */
    @Nullable
    BeanFactory getParentBeanFactory();

    /**
     * 本地工厂(容器)是否包含这个Bean
     */
    boolean containsLocalBean(String name);

}

ConfigurableBeanFactory

/**
 * 定义BeanFactory的配置.
 * 
 * 这边定义了太多太多的api,比如类加载器,类型转化,属性编辑器,BeanPostProcessor,作用域,bean定义,处理bean依赖关系,合并其他ConfigurableBeanFactory,bean如何销毁.
 * 
 * @author DemoTransfer
 * @since 4.3
 */
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {
    //-------------------------------------------------------------------------
    // 定义了两个作用域: 单例和原型.可以通过registerScope来添加.
    // SCOPE_SINGLETON,SCOPE_PROTOTYPE
    //-------------------------------------------------------------------------
    /**
     * 单例
     */
    String SCOPE_SINGLETON = "singleton";
    /**
     * 原型
     */
    String SCOPE_PROTOTYPE = "prototype";
    /**
     * 父容器设置.而且一旦设置了就不让修改
     * 搭配HierarchicalBeanFactory接口的getParentBeanFactory方法
     */
    void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;
    /**
     * 类加载器设置与获取.默认使用当前线程中的类加载器
     * 设置、返回工厂的类加载器
     */
    void setBeanClassLoader(ClassLoader beanClassLoader);
    /**
     * 类加载器设置与获取.默认使用当前线程中的类加载器
     */
    ClassLoader getBeanClassLoader();
    /**
     * 为了类型匹配,搞个临时类加载器.好在一般情况为null,使用上面定义的标准加载器
     * 设置、返回一个临时的类加载器
     */
    void setTempClassLoader(ClassLoader tempClassLoader);
    /**
     * 为了类型匹配,搞个临时类加载器.好在一般情况为null,使用上面定义的标准加载器
     */
    ClassLoader getTempClassLoader();
    /**
     * 是否需要缓存bean metadata,比如bean difinition 和 解析好的classes.默认开启缓存
     * 设置、是否缓存元数据,如果false,那么每次请求实例,都会从类加载器重新加载(热加载)
     */
    void setCacheBeanMetadata(boolean cacheBeanMetadata);
    /**
     * 是否需要缓存bean metadata,比如bean difinition 和 解析好的classes.默认开启缓存
     * 是否缓存元数据
     */
    boolean isCacheBeanMetadata();
    /**
     * 定义用于解析bean definition的表达式解析器
     * Bean表达式分解器
     */
    void setBeanExpressionResolver(BeanExpressionResolver resolver);
    /**
     * 定义用于解析bean definition的表达式解析器
     */
    BeanExpressionResolver getBeanExpressionResolver();
    /**
     * 设置、返回一个转换服务
     */
    void setConversionService(ConversionService conversionService);
    /**
     * 类型转化器
     */
    ConversionService getConversionService();
    /**
     * 设置属性编辑登记员...
     */
    void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);
    /**
     * 注册常用属性编辑器
     */
    void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);
    /**
     * 用工厂中注册的通用的编辑器初始化指定的属性编辑注册器
     */
    void copyRegisteredEditorsTo(PropertyEditorRegistry registry);
    /**
     * BeanFactory用来转换bean属性值或者参数值的自定义转换器
     * 设置、得到一个类型转换器
     * @see #registerCustomEditor
     */
    void setTypeConverter(TypeConverter typeConverter);
    /**
     * BeanFactory用来转换bean属性值或者参数值的自定义转换器
     */
    TypeConverter getTypeConverter();
    /**
     * 增加一个嵌入式的StringValueResolver
     */
    void addEmbeddedValueResolver(StringValueResolver valueResolver);
    /**
     * Determine whether an embedded value resolver has been registered with this
     * bean factory, to be applied through {@link #resolveEmbeddedValue(String)}.
     * @since 4.3
     */
    boolean hasEmbeddedValueResolver();
    /**
     * string值解析器分解指定的嵌入式的值
     */
    String resolveEmbeddedValue(String value);
    /**
     * BeanPostProcessor用于增强bean初始化功能
     * /设置一个Bean后处理器
     */
    void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
    /**
     * 返回Bean后处理器的数量
     */
    int getBeanPostProcessorCount();
    /**
     * 注册范围
     */
    void registerScope(String scopeName, Scope scope);
    /**
     * 返回注册的范围名
     * @see #registerScope
     */
    String[] getRegisteredScopeNames();
    /**
     * 返回指定的范围
     * @see #registerScope
     */
    Scope getRegisteredScope(String scopeName);
    /**
     * 返回本工厂的一个安全访问上下文
     */
    AccessControlContext getAccessControlContext();
    /**
     * 合并其他ConfigurableBeanFactory的配置,包括上面说到的BeanPostProcessor,作用域等
     * 从其他的工厂复制相关的所有配置
     */
    void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);
    /**
     * 给指定的Bean注册别名
     */
    void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException;
    /**
     * 根据指定的StringValueResolver移除所有的别名
     */
    void resolveAliases(StringValueResolver valueResolver);
    /**
     * 返回指定Bean合并后的Bean定义
     */
    BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
    /**
     * 判断指定Bean是否为一个工厂Bean
     */
    boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;
    /**
     * 设置一个Bean是否正在创建
     */
    void setCurrentlyInCreation(String beanName, boolean inCreation);
    /**
     * 返回指定Bean是否已经成功创建
     */
    boolean isCurrentlyInCreation(String beanName);
    /**
     * 注册一个依赖于指定bean的Bean
     */
    void registerDependentBean(String beanName, String dependentBeanName);
    /**
     * 返回依赖于指定Bean的所欲Bean名
     */
    String[] getDependentBeans(String beanName);
    /**
     * 返回指定Bean依赖的所有Bean名
     */
    String[] getDependenciesForBean(String beanName);
    /**
     * 销毁指定的Bean
     */
    void destroyBean(String beanName, Object beanInstance);
    /**
     * 销毁指定的范围Bean
     */
    void destroyScopedBean(String beanName);
    /**
     * 销毁所有的单例类
     */
    void destroySingletons();
}

第二条

第二条接口设计主线是以ApplicationContext应用上下文接口为核心的接口设计。这里涉及到的主要接口设计有,从BeanFactoryListableBeanFactory,再到ApplicationContext,再到我们常用的WebApplicationContext或者ConfigurableApplicationContext接口。我们常用的应用上下文基本上都是ConfigurableApplicationContext或者WebApplicationContext的实现。在这个接口体系中,ListableBeanFactoryHierarchicalBeanFactory两个接口,连接BeanFactory接口定义和ApplicationContext应用上下文的接口定义。对于ApplicationContext接口,它通过继承MessageSource,ResourceLoader,ApplicationEventPublisher接口,在BeanFactory简单IOC容器的基础上添加了许多对高级容器的特性的支持。

ApplicationContext

WebApplicationContext

ConfigurableApplicationContext

MessageSource

MessageSource是一个解析消息的策略接口,它支持参数化与国际化。

/**
 * 用于解析消息的策略接口,支持此类消息的参数化和国际化
 */
public interface MessageSource {

    /**
     * 解析消息,如果没找到code对应的消息就返回defaultMessage
     */
    @Nullable
    String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale);

    /**
     * 解析消息,如果没找到code对应的消息就抛异常

     */
    String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException;

    /**
     * 使用MessageSourceResolvable中的所有属性解析消息
     * MessageSourceResolvable用code[]是啥意思呢???
     */
    String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
}

ListableBeanFactory

BeanFactory定义的都是对单个bean进行的操作,而ListableBeanFactory定义的操作大多数都是返回多个bean或者bean相关元素。从“Listable”就可以看出来,它定义了一些对bean进行列表化的操作。因此,ApplicationContext也可以对bean进行一些列表化操作。

/**
 * 可以枚举所有bean实例,而不是按客户端的请求逐个尝试按名称查找bean
 */
public interface ListableBeanFactory extends BeanFactory {

    /**
     * 是否存在指定name的BeanDefinition
     */
    boolean containsBeanDefinition(String beanName);

    /**
     * 获取BeanFactory中BeanDefinition的数量
     */
    int getBeanDefinitionCount();

    /**
     * 获取所有BeanDefinition的名字
     */
    String[] getBeanDefinitionNames();

    /**
     * 获取指定类型的beanName数组
     */
    String[] getBeanNamesForType(ResolvableType type);

    /**
     * 获取指定类型的beanName数组
     */
    String[] getBeanNamesForType(@Nullable Class<?> type);

    /**
     * 获取指定类型的beanName数组,加了是否包含单例和非懒加载这几个限制
     */
    String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);

    /**
     * 获取指定类型的所有bean
     */
    <T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;

    /**
     * 获取指定类型的所有bean,加了是否包含单例和非懒加载这几个限制
     */
    <T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
            throws BeansException;

    /**
     * 获取指定注解类型的beanNames
     */
    String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);

    /**
     * 获取指定类型的bean对象
     */
    Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;

    /**
     * 根据beanName和指定注解类型获取注解bean对象
     */
    @Nullable
    <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
            throws NoSuchBeanDefinitionException;
}

ResourceLoader

ResourceLoader是一个资源加载的策略接口,继承这个接口说明ApplicationContext有资源加载的功能,这也是Spring容器的第一步操作——加载配置文件。因为配置文件定义了bean以及bean之间的关系,所以只有把配置文件加载进来才能创建、管理bean。

/**
 * 资源加载的策略接口
 */
public interface ResourceLoader {

    /** Pseudo URL prefix for loading from the class path: "classpath:". */
    String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;


    /**
     * 返回指定路径的资源,这里只返回一个,说明不支持模式匹配
     */
    Resource getResource(String location);

    /**
     * 返回统一的ClassLoader,而不是依赖于线程上下文ClassLoader
     */
    @Nullable
    ClassLoader getClassLoader();
}

ResourcePatternResolver

从名字就可以看出来,ResourcePatternResolver对ResourceLoader进行了扩展,它支持解析模式匹配的路径。

/**
  * 解析模式匹配的路径,加载资源
  */
public interface ResourcePatternResolver extends ResourceLoader {

    /**
     * classpath url的前缀
     */
    String CLASSPATH_ALL_URL_PREFIX = "classpath*:";

    /**
     * 解析模式匹配的路径,返回多个Resource
     */
    Resource[] getResources(String locationPattern) throws IOException;

}

ApplicationEventPublisher

ApplicationEventPublisher定义了事件发布的功能,可以将事件发布给注册了此应用所有匹配的监听器。由此可见,ApplicationContet也可以发布事件。

/**
 * 定义了事件发布功能
 */
@FunctionalInterface
public interface ApplicationEventPublisher {

    default void publishEvent(ApplicationEvent event) {
        publishEvent((Object) event);
    }

    /**
     * 通知在此应用程序中注册的所有匹配的listeners
     */
    void publishEvent(Object event);
}

EnvironmentCapable

EnvironmentCapable中只定义了getEnvironment的方法,向外界暴露了Environment接口。Environment是Spring运行时的环境,它包含了profiles和properties。

public interface EnvironmentCapable {
    Environment getEnvironment();
}

文章作者: LeePandar
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 LeePandar !
评论
 上一篇
为什么阿里规定需要在事务注解@Transactional中指定rollbackFor? 为什么阿里规定需要在事务注解@Transactional中指定rollbackFor?
阿里巴巴Java规范:方法【edit】需要在Transactional注解指定rollbackFor或者在方法中显示的rollback。 异常的分类 Throwable:有两个重要的子类:Exception(异常)和Error(错误),
2020-07-30
下一篇 
Linux安装Oracle Linux安装Oracle
官方最低要求配置内存:1G(官方最低要求1G) 硬盘:40G(企业版安装所需4.29G和1.7G数据文件) 准备工作安装环境介绍系统:CentOS 7 64位 Oracle版本:Oracle 11gR2 下载Oracle安装文件官网下载地址
2020-07-23
  目录