Spring IoC体系

    首先我们看一个大致的类图:

    

    在SpringFramework IoC核心的设计中,我们可以看到两个主要的容器系列:一个是实现了BeanFactory的简单容器系列,这类容器提供最基础的IoC容器的功能;一个是实现了ApplicationContext接口的应用上下文,它作为高级形态的IoC容器 ①,提供了很多面向应用的、BeanFactory不具备的新特性。

 

一、BeanFactory(基础容器)

public interface BeanFactory {

    String FACTORY_BEAN_PREFIX = "&";

    // 根据类型获取Bean
    <T> T getBean(Class<T> requiredType) throws BeansException;
    // 根据名称获取Bean
    Object getBean(String name) throws BeansException;
    // 根据名称+类型获取Bean
    <T> T getBean(String name, Class<T> requiredType) throws BeansException;
    // 根据名称+参数获取Bean
    Object getBean(String name, Object... args) throws BeansException; 
    // 是否含有指定名称的Bean
    boolean containsBean(String name);
    // 是否是Singleton类型的Bean
    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
    // 是否是Prototype类型的Bean
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
    // 是否匹配name+类型
    boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
    // 获取指定名称的Bean的Class类型
    Class<?> getType(String name) throws NoSuchBeanDefinitionException;
    // 获取指定名称的Bean的别名数组
    String[] getAliases(String name);
}

    BeanFactory接口作为顶层设计,它定义了IoC容器的基本形态,提供了IoC容器应该遵守的最底层和最基本的服务契约。

    BeanFactory接口最主要的设计是,提供了框架内获取托管Bean的主要API —— getBean方法。

    基础IoC系列容器与其它接口、抽象类、实现类之间的关系:

    

  • AutowireCapableBeanFactory(装配规则IoC)
public interface AutowireCapableBeanFactory extends BeanFactory {

    int AUTOWIRE_NO = 0;
    int AUTOWIRE_BY_NAME = 1;
    int AUTOWIRE_BY_TYPE = 2;
    int AUTOWIRE_CONSTRUCTOR = 3;
    @Deprecated
    int AUTOWIRE_AUTODETECT = 4;

    //--------------------- 装配Bean实例相关的方法 ---------------------
    // 根据Class创建Bean实例
    <T> T createBean(Class<T> beanClass) throws BeansException;
    // 重新填充这个Bean实例注释的字段和方法
    void autowireBean(Object existingBean) throws BeansException;
    // 根据相应的Bean定义装配这个未加工的Object,这实际上是initializeBean方法的超集
    Object configureBean(Object existingBean, String beanName) throws BeansException;
    // 分析Bean实例指定的依赖关系
    Object resolveDependency(DependencyDescriptor descriptor, String beanName)
        throws BeansException; 

    //--------------------- Bean实例生命周期相关的方法 ---------------------
    // 根据指定的类型和装配策略,构造一个新的Bean实例,这实际上autowire方法的超集
    Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck)
        throws BeansException;
    // 根据指定的类型和装配策略,构造一个新的Bean实例
    Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck)
        throws BeansException; 
    // 根据指定的名称和类型,自动装配给定Bean实例的Bean属性
    void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
        throws BeansException; 
    // 根据指定名称的Bean属性值应用于给定的Bean实例
    void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;
    // 初始化原始Bean
    Object initializeBean(Object existingBean, String beanName) throws BeansException;
    // 初始化之前执行BeanPostProcessors
    Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
        throws BeansException;
    // 初始化之后执行BeanPostProcessors
    Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
        throws BeansException;
    // 分析Bean实例指定的依赖关系
    Object resolveDependency(DependencyDescriptor descriptor, String beanName, Set<String>
        autowiredBeanNames, TypeConverter typeConverter) throws BeansException;
}

    AutowireCapableBeanFactory接口主要提供Bean的自动装配规则和初始化能力,其抽象子类AbstractAutoWireCapableBeanFactory,实现了createBean()、autowireBean()和configureBean()方法,封装了初始化Bean的装配逻辑。

AbstractAutoWireCapableBeanFactory内部维护的一些成员变量:

1)allowCircularReferences:是否尝试自动解决bean之间的循环引用,默认为true;

2)allowRawInjectionDespiteWrapping:在循环引用的情况下,是否尝试注入原始bean实例,默认为false;

3)ignoredDependencyTypes:忽略依赖关系检查和自动装配的类型白名单,默认为无;

4)ignoredDependencyInterfaces:忽略依赖关系检查和自动装配的接口白名单,默认只有BeanFactory接口被忽略;

5)factoryBeanInstanceCache:未完成的FactoryBean实例缓存;

FactoryBean name --> BeanWrapper

6)filteredPropertyDescriptorsCache:缓存过滤的属性描述符

bean Class -> PropertyDescriptor array
  • ListableBeanFactory(清单IoC)
public interface ListableBeanFactory extends BeanFactory {
    // 是否包含指定的Bean定义
    boolean containsBeanDefinition(String beanName); 
    // 放回定义的Bean数目
    int getBeanDefinitionCount(); 
    // 返回定义的所有Bean名称
    String[] getBeanDefinitionNames(); 

    // 跟据Bean类型获取bean,它不会检查嵌套的FactoryBean创建的bean 
    String[] getBeanNamesForType(ResolvableType type); 
    String[] getBeanNamesForType(Class<?> type); 
    String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit); 
    <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException; 
    <T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, 
        boolean allowEagerInit) throws BeansException; 

     // 根据注解查找相关BeanName数组
    String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType); 
    // 根据注解查找相关Bean Map
    Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)
        throws BeansException; 
    // 查找一个Bean上的注解
    <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) 
        throws NoSuchBeanDefinitionException; 
}

    ListableBeanFactory接口,可以像清单一样列出该BeanFactory可以生产的所有Bean实例,它的子类DefaultListableBeanFactory和AbstractApplicationContext是初始化Bean的核心。

  • HierarchicalBeanFactory(分层IoC)
public interface HierarchicalBeanFactory extends BeanFactory {
    // 返回父工厂
    BeanFactory getParentBeanFactory();
    // 是否包含指定名称的Bean
    boolean containsLocalBean(String name);
}

    HierarchicalBeanFactory接口表示IoC容器的分层结构。它比较简单,主要是提供获取父BeanFactory的功能,比如让当前的BeanFactory加载父BeanFactory加载的Bean定义,弥补ListableBeanfactory欠缺的功能。

  • ConfigurableBeanFactory(配置IoC)
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {

    String SCOPE_SINGLETON = "singleton"; 
    String SCOPE_PROTOTYPE = "prototype";

    // 设置父BeanFactory
    void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException; 
    // 以下四个:设置和获取BeanClassLoader
    void setBeanClassLoader(ClassLoader beanClassLoader); 
    ClassLoader getBeanClassLoader(); 
    void setTempClassLoader(ClassLoader tempClassLoader); 
    ClassLoader getTempClassLoader();

    // 是否需要缓存Bean Metadata(热加载开关)
    void setCacheBeanMetadata(boolean cacheBeanMetadata); 
    boolean isCacheBeanMetadata();

    // 定义用于解析BeanDefinition的表达式解析器
    void setBeanExpressionResolver(BeanExpressionResolver resolver); 
    BeanExpressionResolver getBeanExpressionResolver();

    // 类型转换服务
    void setConversionService(ConversionService conversionService); 
    ConversionService getConversionService();

    // 属性编辑器
    void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);

    // BeanFactory用来转换bean属性值或者参数值的自定义转换器
    void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor>
        propertyEditorClass); 
    void copyRegisteredEditorsTo(PropertyEditorRegistry registry);

    // 类型转换器
    void setTypeConverter(TypeConverter typeConverter); 
    TypeConverter getTypeConverter(); 
    void addEmbeddedValueResolver(StringValueResolver valueResolver); 
    String resolveEmbeddedValue(String value);

    // Bean处理器
    void addBeanPostProcessor(BeanPostProcessor beanPostProcessor); 
    int getBeanPostProcessorCount();

    // 作用域定义
    void registerScope(String scopeName, Scope scope); 
    String[] getRegisteredScopeNames(); 
    Scope getRegisteredScope(String scopeName);

    // 访问权限控制
    AccessControlContext getAccessControlContext();

    // 合并其他ConfigurableBeanFactory的配置,包括上面说到的BeanPostProcessor,作用域等
    void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);

    // Bean别名处理
    void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException; 
    void resolveAliases(StringValueResolver valueResolver); 

    // Bean定义处理
    BeanDefinition getMergedBeanDefinition(String beanName)
        throws NoSuchBeanDefinitionException; 
    boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;

    // Bean创建状态控制.在解决循环依赖时有使用
    void setCurrentlyInCreation(String beanName, boolean inCreation); 
    boolean isCurrentlyInCreation(String beanName);

    // 处理Bean依赖
    void registerDependentBean(String beanName, String dependentBeanName); 
    String[] getDependentBeans(String beanName); 
    String[] getDependenciesForBean(String beanName);

    // 销毁Bean
    void destroyBean(String beanName, Object beanInstance); 
    void destroyScopedBean(String beanName); 
    void destroySingletons();
}

    ConfigurableBeanFactory接口,提供了配置BeanFactory的能力以及作为BeanFactory的界面来使用。值得注意的是,setParentBeanFactory()方法只能设置一次,不能改变,而setBeanClassLoader()方法,也只能应用于BeanDefinition。

    Bean实例有两个作用域:singleton 单例和 prototype 原型,应用于方法registerScope()。值得注意的是,除了容器内Bean实例的多寡之外,它们的生命周期也是不同的。不管何种作用域,IoC容器都会调用所有Bean实例的初始化回调方法,而对prototype作用域的Bean实例而言,任何生命周期内的析构回调方法都将不被调用。也就是说,Spring不对一个prototype bean的整个生命周期负责,容器在初始化、配置、修饰或者是装配完一个prototype实例,并将它交给客户端后,就对该prototype实例不闻不问了。清理prototype作用域的Bean实例并释放任何prototype实例所持有的昂贵资源,都将是客户端代码的职责。

    其抽象子类 AbstractBeanFactory,不仅提供了ConfigurableBeanFactory SPI ③的全部功能,并且继承了DefaultSingletonBeanRegistry,提供单例缓存和顺序执行Bean释放的能力。

AbstractBeanFactory内部维护的一些成员变量:

1)cacheBeanMetadata:是否缓存bean元数据,默认为true;

2)hasInstantiationAwareBeanPostProcessors:表示是否已经注册了InstantiationAwareBeanPostProcessor,默认为false;

3)hasDestructionAwareBeanPostProcessors:表示是否已经注册了DestructionAwareBeanPostProcessor,默认为false;

4)beanPostProcessors:要在createBean中应用的beanPostProcessors集;

5)scopes:容器中bean实例作用域的映射集;

6)mergedBeanDefinitions:beanName和RootBeanDefinition的映射集;

7)alreadyCreated:已经创建过至少一次的beanName;

8)prototypesCurrentlyInCreation:当前正在创建的beanName,使用ThreadLocal;

  • ConfigurableListableBeanFactory(配置清单IoC)
public interface ConfigurableListableBeanFactory
        extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {

    // 设置忽略的依赖关系,注册找到的特殊依赖
    void ignoreDependencyType(Class<?> type); 
    void ignoreDependencyInterface(Class<?> ifc); 
    void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue); 
    boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
            throws NoSuchBeanDefinitionException;

    // 获取bean定义 (可以访问属性值跟构造方法的参数值)
    BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

    // 迭代BeanNames
    Iterator<String> getBeanNamesIterator();

    // 清除元数据缓存
    void clearMetadataCache();

    // 锁定配置信息.在调用refresh时会使用到.
    void freezeConfiguration(); 
    boolean isConfigurationFrozen();

    // 预加载不是懒加载的单例.用于解决循环依赖问题
    void preInstantiateSingletons() throws BeansException;
}

    扩展至ConfigurableBeanFactory接口。该扩展接口除了添加访问BeanDefinition和配置信息外,还提供了预实例化单例的能力。

    其实现类 DefaultListableBeanFactory是基础IoC默认的完整实现,可以作为独立的bean工厂使用,也可以作为定制bean工厂的超类。

DefaultListableBeanFactory内部维护的一些成员变量:

1)allowBeanDefinitionOverriding:是否允许同名不同BeanDefinition再次进行注册;

2)allowEagerClassLoading:是否允许eager类(相对于lazy)加载,甚至延迟初始化bean的加载;

3)configurationFrozen:是否可以为所有bean 缓存BeanDefinition元数据;

4)resolvableDependencies:依赖类型和其对应的自动绑定值的映射集;

5)beanDefinitionMap:BeanDefinition对象的映射集;

6)allBeanNamesByType:非单例bean名称的映射集;

7)singletonBeanNamesByType:单例bean名称的映射集;

8)beanDefinitionNames:BeanDefinition名称列表,以注册顺序;

 

二、ApplicationContext(应用上下文)

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, 
		HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, 
		ResourcePatternResolver {

	// 返回此应用上下文的唯一ID
	String getId();

	// 返回此上下文所属的部署应用程序的名称
	String getApplicationName();

	// 返回此上下文的友好名称
	String getDisplayName();

	// 首次加载此上下文时返回时间戳
	long getStartupDate();

	// 返回父上下文,如果为null,即上下文层次结构的根
	ApplicationContext getParent();

	// 公开AutowireCapableBeanFactory
	AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}

        作为应用上下文,在它的设计中,一方面,可以看到它继承了基础IoC体系中的 AutowireCapableBeanFactory、HierarchicalBeanFactory 接口,具备了基础IoC容器的基本能力,另一方面,通过继承 MessageSource、ApplicationEventPublisher、ResourceLoader 等接口,它被赋予了许多高级IoC的特性,而且为了在Web环境使用它,还设计了 WebApplicationContext 接口,通过继承ThemeSource接口来添加附件的功能。所以,一般建议使用 ApplicationContext 作为IoC容器的基本形式。

        应用上下文系列容器与其它接口、抽象类、实现类之间的关系:

        

  • WebApplicationContext(Web上下文)
public interface WebApplicationContext extends ApplicationContext {

    // 作用域
	String SCOPE_REQUEST = "request";
	String SCOPE_SESSION = "session";
	String SCOPE_GLOBAL_SESSION = "globalSession";
	String SCOPE_APPLICATION = "application";
	String SERVLET_CONTEXT_BEAN_NAME = "servletContext";
    // environment bean
	String CONTEXT_PARAMETERS_BEAN_NAME = "contextParameters";
	String CONTEXT_ATTRIBUTES_BEAN_NAME = "contextAttributes";
    // 绑定的Context属性名
	String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";

	// 获取标准Servlet API
	ServletContext getServletContext();
}

    除提供标准的应用上下文生命周期的功能以外,WebApplicationContext通常被用作Web应用程序的上下文界面来使用。 每个应用程序都有单个根上下文,而应用程序中的每个servlet(包括MVC框架中的调度程序servlet)都有自己的子上下文。

    GenericWebApplicationContext是其通用实现,适用于Web环境,但不适用于web.xml中的声明式安装,而是设计用于编程式设置。

    XmlWebApplicationContext是最常见的WebApplicationContext。

  • ConfigurableApplicationContext(可配置上下文)
public interface ConfigurableApplicationContext extends ApplicationContext, 
       Lifecycle, Closeable {

	// 多个上下文配置路径之间的分隔符
	String CONFIG_LOCATION_DELIMITERS = ",; \t\n";
    // Bean工厂中的属性名
	String CONVERSION_SERVICE_BEAN_NAME = "conversionService";
	String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";
	String ENVIRONMENT_BEAN_NAME = "environment";
	String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties";
	String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";


	void setId(String id);
	void setParent(ApplicationContext parent);
	ConfigurableEnvironment getEnvironment();
	void setEnvironment(ConfigurableEnvironment environment);

	// 添加一个新的BeanFactoryPostProcessor
	void addBeanFactoryPostProcessor(BeanFactoryPostProcessor beanFactoryPostProcessor);
	// 添加上下文监听器
	void addApplicationListener(ApplicationListener<?> listener);
	// 刷新上下文
	void refresh() throws BeansException, IllegalStateException;
	// 注册一个关闭钩子 ShutdownHook
	void registerShutdownHook();
	// 关闭上下文
	void close();
	// 是否活跃,即是否已刷新至少一次并尚未关闭
	boolean isActive();
	//
	ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
}

    扩展了ApplicationContext界面中的应用上下文SPI,通常配置和生命周期相关方法被封装在这里,以避免使它们对ApplicationContext客户端代码显而易见。

    AbstractApplicationContext是其抽象实现,其refresh()方法只能被调用一次。典型的用法是通过BeanDefinitionRegistry接口注册各种bean定义,然后调用AbstractApplicationContext#refresh()方法来初始化具有应用上下文语义的Bean(如ApplicationContextAware、BeanFactoryPostProcessors等)。

    GenericApplicationContext是其通用实现,也是通用的ApplicationContext实现。 

 

三、其它相关的一些特性

  • FactoryBean:
public interface FactoryBean<T> {

	// 返回Bean实例,如果是单实例,则该实例会放到IoC容器中的单实例缓存池中
	T getObject() throws Exception;
	// 返回Bean类型
	Class<?> getObjectType();
	// Bean实例的作用域是否是singleton
	boolean isSingleton();
}

        其实这很好理解,一个是Bean工厂,是IoC容器;一个是工厂Bean,用来生产对象或修饰对象生成的一类Bean。相对应的,一个是IoC设计模式,Inversion of Control 控制反转或者说是依赖注入,就是把组件之间的依赖关系从代码中移出去,通过可读的文本配置来进行浏览和管理,降低维护成本提高管理水平;一个是抽象工厂模式和修饰模式,它提供了一种封装机制,比如封装了Proxy、RMI、JNDI,在合适的场合将它们修饰进生产出来的对象中,所以,它返回的对象并不是指定一个类的实例。

        你可以通过转义符“&”来获得FactoryBean本身,而非这个FactoryBean产生出来的对象  ②。

        Spring 自身提供了70多个FactoryBean的实现,并且从Spring 3.0版本开始,FactoryBean开始支持泛型,接口声明改为FactoryBean<T>的形式。

  • ObjectFactory:
public interface ObjectFactory<T> {

	// 获取Bean实例
	T getObject() throws BeansException; 
}

        简单来说,对象工厂,用来生产Bean实例的,它只有一个方法 getObject()

        ObjectFactory接口和FactoryBean接口有些类似,但实际上,FactoryBean的实现是作为一个SPI来在BeanFactory内部使用的,它相当于是BeanFactory#getBean()的代理。而ObjectFactory实现是被用来注入到其它Bean中作为API来使用的,这在Sprin IoC核心的源码中随处可见,通过ObjectFactory实现来取得我们想要的Bean实例。

  • BeanWrapper:
public interface BeanWrapper extends ConfigurablePropertyAccessor {

	// 返回由此对象包装的bean实例
	Object getWrappedInstance();

	// 返回包装的Bean实例的类型
	Class<?> getWrappedClass();

	// 获取包装对象的属性描述符
	PropertyDescriptor[] getPropertyDescriptors();
	PropertyDescriptor getPropertyDescriptor(String propertyName) 
		throws InvalidPropertyException;

	boolean isAutoGrowNestedPaths();
	void setAutoGrowNestedPaths(boolean autoGrowNestedPaths);

	void setAutoGrowCollectionLimit(int autoGrowCollectionLimit);
	int getAutoGrowCollectionLimit();
}

        BeanWrapper接口,持有创建出来的Bean对象,封装持有的对象的行为。但事实上它并不简单,由于其继承了属性访问接口、属性编辑注册接口、类型转换接口,不仅可以单个或批量的设置以及访问被包装对象的属性值,多种不同类型的属性值类型转换,还支持可以无限深度的设置嵌套属性 ④。

        通常情况下,不建议在应用程序中直接使用BeanWrapper,而是采用DataBinder或BeanFactory。因为大部分情况下,BeanWrapper是在IoC容器内部进行使用,所有Bean实例的属性设置也都是交给它来实现,以统一的方式来访问Bean属性。

        

  1. PropertyAccessor接口:属性访问器,定义了各种访问bean属性的方法;
  2. PropertyEditorRegistry接口:属性编辑器,提供将配置文件中字面值转换为具体属性类型的对象的能力;
  3. TypeConverter接口:类型转换器,通常与PropertyEditorRegistry接口一起实现;
  4. DataBinder接口:数据绑定,将属性值设置到目标对象上的绑定,支持验证和绑定结果分析;
  5. BeanWrapperImpl实现类:对BeanWrapper接口的默认实现,内部会对被包装对象的Class进行内省分析,其PropertyDescriptor结果将缓存在CachedIntrospectionResults对象中。
  • BeanDefinition:
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

    String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON; 
    String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;

    //------------- Bean角色 -------------
    int ROLE_APPLICATION = 0; 
    int ROLE_SUPPORT = 1; 
    int ROLE_INFRASTRUCTURE = 2;

    String getParentName(); 
    void setParentName(String parentName);

    String getBeanClassName(); 
    void setBeanClassName(String beanClassName);

    String getFactoryBeanName(); 
    void setFactoryBeanName(String factoryBeanName);

    String getFactoryMethodName(); 
    void setFactoryMethodName(String factoryMethodName);

    String getScope(); 
    void setScope(String scope);

    boolean isLazyInit(); 
    void setLazyInit(boolean lazyInit);

    String[] getDependsOn(); 
    void setDependsOn(String... dependsOn);

    boolean isAutowireCandidate(); 
    void setAutowireCandidate(boolean autowireCandidate);

    boolean isPrimary(); 
    void setPrimary(boolean primary);

    ConstructorArgumentValues getConstructorArgumentValues();
    MutablePropertyValues getPropertyValues(); 

    boolean isSingleton(); 
    boolean isPrototype(); 
    boolean isAbstract(); 
    int getRole(); 
    String getDescription(); 
    String getResourceDescription(); 
    BeanDefinition getOriginatingBeanDefinition();
}

       BeanDefinition接口表示Bean定义,IoC容器是用来解构和管理对象依赖关系的,对IoC容器来说,BeanDefinition就是对依赖反转模式中管理的对象依赖关系的数据抽象,也是IoC容器用来实现依赖反转功能的核心数据结构,依赖反转功能都是围绕着对这个BeanDefinition的处理来完成。

        BeanDefinition类图如下:

        

  1. AttributeAccessor接口:提供访问name/value属性的能力;
  2. BeanMetadataElement接口:提供访问source(配置源)的能力;
  3. AnnotatedBeanDefinition接口:提供管理BeanDefinition注解的数据的能力;
  4. AbstractBeanDefinition抽象类:提供BeanDefinition属性,公共判断,重写了equals、hashCode、toString方法。 

    AbstractBeanDefinition内部字段:

    // bean原始类型
    private volatile Object beanClass;  
    // bena的作用域
    private String scope = "";
    // 是否单例
    private boolean singleton = true;
    // 是否原型
    private boolean prototype = false;
    // 是否抽象定义
    private boolean abstractFlag = false;
    // 是否预实例化
    private boolean lazyInit = false;
    // 自动装配模式
    private int autowireMode = 0;
    // 是否依赖检查
    private int dependencyCheck = 0;
    // 依赖的bean
    private String[] dependsOn;
    // 装配候选人
    private boolean autowireCandidate = true;
    // 单值依赖时的优先权
    private boolean primary = false;
    // 非公开访问允许
    private boolean nonPublicAccessAllowed = true;
    // 宽松的构造方法
    private boolean lenientConstructorResolution = true;
    // 构造函数参数列表
    private ConstructorArgumentValues constructorArgumentValues;
    // 多个属性值
    private MutablePropertyValues propertyValues;
    // 方法覆盖
    private MethodOverrides methodOverrides = new MethodOverrides();
    // FactoryBean名称
    private String factoryBeanName;
    // FactoryBean方法名
    private String factoryMethodName;
    // <init-method>方法名
    private String initMethodName;
    // <destroy>方法名
    private String destroyMethodName;
    // init方法名
    private boolean enforceInitMethod = true;
    // destroy方法名
    private boolean enforceDestroyMethod = true;
    // 合成标识
    private boolean synthetic = false;
    // 角色
    private int role = 0;
    // 描述信息
    private String description;
    // 资源位置
    private Resource resource;
    // 装配后续的限定词
    private final Map<String, AutowireCandidateQualifier> qualifiers = 
           new LinkedHashMap<String, AutowireCandidateQualifier>(0);
  5. RootBeanDefinition实现类:表示运行时统一的(合并)BeanDefinition视图;
  6. ChildBeanDefinition实现类:表示子BeanDefinition具有父BeanDefinition的固有依赖;
  7. GenericBeanDefinition实现类:Spring 2.5以后,该实现是标准Bean定义目的的一站式服务,允许动态的定义父子依赖。一般来说,是以编程方式注册用户可见Bean定义的首选,是ChildBeanDefinition和RootBeanDefinition更好的替代品。

        另外还有一个BeanDefinitionHolder类,不在上面的类图里,但却是BeanDefinition的封装类。该实例持有BeanDefinition、Bean名字以及别名等信息,用它来临时保存BeanDefinition来完成IoC容器注册。

  • BeanDefinitionRegistry
public interface BeanDefinitionRegistry extends AliasRegistry {

    // 往注册表中注册一个新的BeanDefinition  
    void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) 
        throws BeanDefinitionStoreException; 
    // 根据beanName移除已注册的BeanDefinition实例
    void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
    // 根据beanName获取BeanDefinition实例
    BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; 
    // beanName是否已注册
    boolean containsBeanDefinition(String beanName);
    // 获取注册表中所有BeanDefinition实例的beanName
    String[] getBeanDefinitionNames();
    // 获取注册表中BeanDefinition实例的数量
    int getBeanDefinitionCount();
    // beanName是否被占用
    boolean isBeanNameInUse(String beanName);
}

        BeanDefinitionRegistry接口主要作用是向注册表中注册BeanDefinition实例,以完成Bean注册的过程。实现类一般通过一个HashMap类型的成员变量beanDefinitionMap来持有载入的BeanDefinition。

        

  1. AliasRegistry接口:提供别名注册的能力,实现类通常以一个HashMap类型的成员变量aliasMap来持有载入的Alias;
  2. SingletonBeanRegistry接口:提供单例对象注册的能力;
  3. DefaultSingletonBeanRegistry实现类:单例对象的通用注册表。它作为SingletonBeanRegistry接口的默认实现,其内部维护了四个集合(Map和Set)作为单例Bean的注册表,两个Map维护Bean实例的依赖关系,还支持登记DisposableBean实例,以执行适当的关闭顺序。 

    DefaultSingletonBeanRegistry内部维护的一些成员变量:

    1)NULL_OBJECT:表示空值单例对象,用作并发映射的标记值;

    2)singletonObjects:单例对象缓存池

    bean name --> bean instance

    3)singletonFactories:单例ObjectFactory的缓存池

    bean name --> ObjectFactory

    4)earlySingletonObjects:预先暴露的单例对象缓存池

    bean name --> ObjectFactory

    5)registeredSingletons:单例对象的注册表;

    6)singletonsCurrentlyInCreation:当前正在创建的beanName,使用ConcurrentHashMap;

    7)inCreationCheckExclusions:当前在初始化检查中被排除的beanName,使用ConcurrentHashMap;

    8)suppressedExceptions:抑制异常的白名单,用于关联相关原因;

    9)singletonsCurrentlyInDestruction:标识当前BeanFactory是否在destroy;

    10)disposableBeans:登记的DisposableBean实例,以执行适当的关闭顺序

    bean name --> disposable instance

    11)containedBeanMap:两个Bean之间的依赖(包含)关系的映射集;

    bean name --> contains bean names Set

    12)dependentBeanMap:bean之间依赖的映射集;

    bean name --> dependent bean names Set

    13)dependenciesForBeanMap:bean之间依赖的映射集;

    bean name --> bean's dependencies bean names Set
  4. FactoryBeanRegistrySuppourt抽象类:在DefaultSingletonBeanRegistry的基础上增加了对FactoryBeans创建的单例对象的缓存池。 

    DefaultSingletonBeanRegistry内部维护的一些成员变量:

    1)factoryBeanObjectCache:FactoryBeans创建的单例对象缓存池

    FactoryBean name --> object
  • BeanDefinitionReader
public interface BeanDefinitionReader {
    // 获取BeanDefinitionRegistry 
    BeanDefinitionRegistry getRegistry();
    // 获取Bean名称生成器
    BeanNameGenerator getBeanNameGenerator();

    ResourceLoader getResourceLoader();
    ClassLoader getBeanClassLoader(); 

    //载入BeanDefinition
    int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException;
    int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException;
    int loadBeanDefinitions(String location) throws BeanDefinitionStoreException;
    int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException;
}

        简单来说,就是BeanDefinition读取器的统一界面,从给定的资源或字符串位置参数加载或注册BeanDefinition。具体的实现类特定于它们定义的格式。

        

        另外还有两个类值得注意:

            — AnnotatedBeanDefinitionReader,用于编程方式注册的Bean定义;

            — BeanDefinitionDocumentReader,用于解析包含BeanDefinition的DOM文档,组合                   XmlBeanDefinitionReader和BeanDefinitionParserDelegate来实现。

  • Resource
public interface Resource extends InputStreamSource {

    // 是否存在
	boolean exists();
	// 是否可读
	boolean isReadable();
	// 是否打开
	boolean isOpen();

	URL getURL() throws IOException;
	URI getURI() throws IOException;
	File getFile() throws IOException;

	// 资源的长度
	long contentLength() throws IOException;
	// 获取文件名
	String getFilename();
	// 返回当前Resource表示的底层资源的最后修改时间
	long lastModified() throws IOException;
	// 返回此资源的描述信息,用于在使用资源时输出错误
	String getDescription();

	// 创建相对于此底层资源的资源
	Resource createRelative(String relativePath) throws IOException;
}

        JDK操作底层资源的接口基本上都是 java.net.URL、java.io.File 等,这就增加了系统的复杂性,因此Spring抽象出一个Resource接口 ,它封装了对具体资源的I/O操作,提供了统一的访问外部资源的策略界面。 

        

  • ResourceLoader
public interface ResourceLoader {

    // 从类路径加载的伪URL前缀: "classpath:"
	String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;

	Resource getResource(String location);
	ClassLoader getClassLoader();
}

        同样是加载资源的策略界面,该接口主要的作用是判断传入的Resource相关字符串,根据location参数返回不同的Resource。 所以,它可以看做是Resource的工厂类。

        

  1. DefaultResourceLoader实现类:是ResourceLoader接口的默认实现,通常内部由ResourceEditor使用。

    DefaultResourceLoader获取Resource时,默认策略:

      - 首先判断指定的location是否含有“/”前缀,有则返回ClassPathContextResource; 
      - 然后判断指定的location是否含有“classpath:”前缀,有则把location去掉“classpath:”前缀返回对应的ClassPathResource; 
      - 否则就把它当做一个URL来处理,封装成一个UrlResource返回; 
      - 如果当做URL处理也失败的话,就把location对应的资源当成是一个ClassPathContextResource返回。 

  2. ResourcePatternResolver接口:提供将位置模式字符解析为Resource对象的能力,是ResourceLoader策略界面的扩展。 

    locationPattern前缀的,默认策略:

        classpath   : 用于加载类路径(包括jar包)中的一个且仅一个资源; 
        classpath* : 用于加载类路径(包括jar包)中的所有匹配的资源,可使用Ant路径模式。

 

 

注:

    ① 本篇幅中的IoC容器,均指的是SpringFramework的IoC系列容器;

    ② Dereference(间接引用),一个在C/C++中应用的比较多的术语,它表示变量所指向的是所引用对象的本身数据,而不是对象的内存地址。在C++中,“*”是解引用符号,“&”是引用符号;

    ③ SPI(Service Provider Interface),表示被第三方来实现或扩展的API,它可以用来扩展框架或实现组件以替换功能。

    ④ 值得注意的是,设置对象属性值时存在一些潜在的约定规则,比如:

name指向属性name,与getName() 、isName() 和 setName()相对应。
account.name指向属性account的嵌套属性name,与之对应的是getAccount().setName()和getAccount().getName()
account[2]指向索引属性account的第三个元素,索引属性可能是一个数组(array)、列表(list)或其它天然有序的容器。
account[COMPANYNAME]指向一个Map实体account中以COMPANYNAME作为键值(key)所对应的值
 

 

参考:

转载于:https://my.oschina.net/duofuge/blog/1058204

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值