美文网首页
SpringIOC容器设计

SpringIOC容器设计

作者: 一觉睡到丶小时候 | 来源:发表于2020-07-24 15:05 被阅读0次

    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();
    }
    

    相关文章

      网友评论

          本文标题:SpringIOC容器设计

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