转载

SpringIOC容器设计

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

  • BeanFactory

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

  • ApplicationContext

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

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

SpringIOC容器设计

两条设计主线

第一条

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

SpringIOC容器设计

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容器的基础上添加了许多对高级容器的特性的支持。

SpringIOC容器设计

SpringIOC容器设计

SpringIOC容器设计

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();
}
原文  http://likeyou.cool/2020/07/24/springioc-rong-qi-she-ji/
正文到此结束
Loading...