在Spring IoC容器的设计中,作者设计了两个接口来表示容器
BeanFactory
BeanFactory简单粗暴,可以理解为HashMap,key是BeanName,value是Bean实例,通常只提供put和get。这系列容器只实现了容器的最基本功能,可看做为简单容器。
ApplicationContext
ApplicationContext应用上下文,它作为容器的高级形态而存在。应用上下文在简单容器的基础上,增加了许多面向框架的特性,同时对应用环境做了许多适配。
Spring通过定义BeanDefinition来管理基于Spring的应用中的各种对象以及它们之间的相互依赖关系。对IoC容器来说,BeanDefinition就是依赖反转模式中管理的对象依赖关系的数据抽象,也是容器实现依赖反转功能的核心数据结构,依赖反转功能都是围绕这个BeanDefinition的处理来完成的。
第一条接口设计的主线是从接口 BeanFactory
到 HierarchicalBeanFactory
再到 ConfigurableBeanFactory
,是一条主要的 BeanFactory
设计路径。在这条接口设计路径中, BeanFactory
接口定义了基本的IOC容器的规范。在这个接口定义中.包括了 getBean()
这样的IOC容器的基本方法(通过这个方法可以从容器中取得Bean)。 HierarchicalBeanFactory
接口在继承了 BeanFactory
的基本接口之后,增加了 getParentBeanFactory()
的接口功能,使 BeanFactory
具备了双亲IOC容器的管理功能.在接下来的 ConfigurableBeanFactory
接口中,主要定义了一些对 BeanFactory
的配置功能,比如通过 setParentBeanFactory()
设置双亲IOC容器,通过 addBeanPostProcessor()
配置Bean后置处理器等等。通过这些接口设计的叠加,定义了 BeanFactory
就是简单IOC容器的基本功能。
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); }
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); }
/** * 定义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
应用上下文接口为核心的接口设计。这里涉及到的主要接口设计有,从 BeanFactory
到 ListableBeanFactory
,再到 ApplicationContext
,再到我们常用的 WebApplicationContext
或者 ConfigurableApplicationContext
接口。我们常用的应用上下文基本上都是 ConfigurableApplicationContext
或者 WebApplicationContext
的实现。在这个接口体系中, ListableBeanFactory
和 HierarchicalBeanFactory
两个接口,连接 BeanFactory
接口定义和 ApplicationContext
应用上下文的接口定义。对于 ApplicationContext
接口,它通过继承 MessageSource
, ResourceLoader
, ApplicationEventPublisher
接口,在 BeanFactory
简单IOC容器的基础上添加了许多对高级容器的特性的支持。
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; }
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是一个资源加载的策略接口,继承这个接口说明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对ResourceLoader进行了扩展,它支持解析模式匹配的路径。
/** * 解析模式匹配的路径,加载资源 */ public interface ResourcePatternResolver extends ResourceLoader { /** * classpath url的前缀 */ String CLASSPATH_ALL_URL_PREFIX = "classpath*:"; /** * 解析模式匹配的路径,返回多个Resource */ Resource[] getResources(String locationPattern) throws IOException; }
ApplicationEventPublisher定义了事件发布的功能,可以将事件发布给注册了此应用所有匹配的监听器。由此可见,ApplicationContet也可以发布事件。
/** * 定义了事件发布功能 */ @FunctionalInterface public interface ApplicationEventPublisher { default void publishEvent(ApplicationEvent event) { publishEvent((Object) event); } /** * 通知在此应用程序中注册的所有匹配的listeners */ void publishEvent(Object event); }
EnvironmentCapable中只定义了getEnvironment的方法,向外界暴露了Environment接口。Environment是Spring运行时的环境,它包含了profiles和properties。
public interface EnvironmentCapable { Environment getEnvironment(); }