Spring IOC(一)体系结构

Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html)

BeanFactory 是Spring IOC 容器的鼻祖,是 IOC 容器的基础接口,所有的容器都是从它这里继承实现而来,可见其地位。BeanFactory 提供了最基本的 IOC 容器的功能,即所有的容器至少需要实现的标准。

一、BeanFactory

public interface BeanFactory {

    String FACTORY_BEAN_PREFIX = "&";

    // 1. getBean
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException; // 2. @since 5.1
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType); // 3. containsBean
boolean containsBean(String name); // 4. 单例、多例。 bean 的生命周期
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException; // 5. 匹配 bean 的 Class 类型或泛型(ResolvableType)
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException; // 6. 其它属性
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
String[] getAliases(String name);
}

这些接口定义勾画出了 IOC 容器的基本方法特性。BeanFactory 功能如下:

  1. BeanFactory 是 Spring 容器的 Root Interface
  2. BeanFactory 持有 BeanDefinition,每一个 bean 都有独有的名字。BeanFactory 可以返回单例或多例的对象,取决于 Bean 定义文件。
  3. 可以通过 setters,constructors 进行依赖注入更好,其实这也是常用的方法。
  4. BeanFactory 通过载入配置源文件(XML 文件)的方式,来配置 Bean。
  5. BeanFactory 支持的 bean 生命周期的顺序。有以下接口:
    1. BeanNameAware#setBeanName
    2. BeanClassLoaderAware#setBeanClassLoader
    3. BeanFactoryAware#setBeanFactory
    4. ResourceLoaderAware#setResourceLoader
    5. ApplicationEventPublisherAware#setApplicationEventPublisher
    6. MessageSourceAware#setMessageSource
    7. ApplicationContextAware#setApplicationContext
    8. ServletContextAware#setServletContext
    9. BeanPostProcessors#postProcessBeforeInitialization
    10. InitializingBean#afterPropertiesSet
    11. a custom init-method definition
    12. BeanPostProcessors#postProcessAfterInitialization
    13. DisposableBean#destroy
    14. a custom destroy-method definition

BeanFactory 作为最顶层的一个接口类,它定义了 IOC 容器的基本功能规范,BeanFactory 有三个直接子类接口:ListableBeanFactory、HierarchicalBeanFactory 和 AutowireCapableBeanFactory,还有一个实现类 SimpleJndiBeanFactory。所以接下来依次分析三个子接口。

二、HierarchicalBeanFactory 可分层次 BeanFactory

从 HierarchicalBeanFactory 接口开始就有了父子工厂的概念。

public interface HierarchicalBeanFactory extends BeanFactory {
// 1. 获取父工厂
BeanFactory getParentBeanFactory();
// 2. 在当前工厂(不向上查找父工厂)中获取指定的 bean
boolean containsLocalBean(String name);
}

三、ListableBeanFactory 可枚举的 BeanFactory

从 ListableBeanFactory 接口开始可以枚举出本工厂生产的所有 bean 了。

public interface ListableBeanFactory extends BeanFactory {
// 1. 查找 BeanDefinition
boolean containsBeanDefinition(String beanName);
int getBeanDefinitionCount();
String[] getBeanDefinitionNames(); // 2. 根据类型查找所有 bean 的名称,包括 FactoryBean
// includeNonSingletons=false 表示只取单例;
// allowEagerInit=true 表示立即加载,false 表示延迟加载。注意:FactoryBean 都是立刻加载的
String[] getBeanNamesForType(Class<?> type);
String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons,
boolean allowEagerInit); // 3. 根据类型查找所有 bean,返回 <beanName, bean>
<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;
<T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons,
boolean allowEagerInit) throws BeansException; // 4.1 根据类上的注解类型查找指定的 bean
String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);
Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)
throws BeansException;
// 4.2 查找指定 bean 上的注解
<A extends Annotation> A findAnnotationOnBean(String beanName,
Class<A> annotationType) throws NoSuchBeanDefinitionException;
}

总结一下:

  1. 从这个工厂接口开始,可以枚举列出工厂可以生产的所有实例。即可以只查找 beanName,也可以查找对应的对象实例。
  2. 从这个工厂接口开始,BeanDefinition 登场了。
  3. 注意如果是一个层次继承的工厂,则只会列出当前工厂的实例,而不会列出祖先层的实例。

四、AutowireCapableBeanFactory 可自动装配的 BeanFactory

从 AutowireCapableBeanFactory 接口开始可以自动装配 bean 了。

AutowireCapableBeanFactory 直接继承自 BeanFacotory,它扩展了自动装配的功能,根据类定义 BeanDefinition 装配 Bean、执行后置处理器等。值得注意的是,这个接口并没有被 ApplicationContext 继承,因为应用程序几乎不用用到这些接口,当然也可以通过 ApplicationContext#getAutowireCapableBeanFactory() 获得这个 BeanFactory 实例。

public interface AutowireCapableBeanFactory extends BeanFactory {

    // 1. 自动装配的模式,AUTOWIRE_AUTODETECT 已废弃
int AUTOWIRE_NO = 0;
int AUTOWIRE_BY_NAME = 1;
int AUTOWIRE_BY_TYPE = 2;
int AUTOWIRE_CONSTRUCTOR = 3;
int AUTOWIRE_AUTODETECT = 4; //-------------------------------------------------------------------------
// Typical methods for creating and populating external bean instances
//-------------------------------------------------------------------------
// 2. 默认的方式创建、自动装配、配置 bean
<T> T createBean(Class<T> beanClass) throws BeansException;
void autowireBean(Object existingBean) throws BeansException;
Object configureBean(Object existingBean, String beanName) throws BeansException; //-------------------------------------------------------------------------
// Specialized methods for fine-grained control over the bean lifecycle
//-------------------------------------------------------------------------
// 3. 根据给定的策略,创建、自动装配、配置 bean
Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
throws BeansException; // 4. bean 属性注入
void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException; // 5. bean 生命周期相关的初始化,如 BeanFactoryAware#setBeanFactory、InitializingBean#afterPropertiesSet
Object initializeBean(Object existingBean, String beanName) throws BeansException;
void destroyBean(Object existingBean); // 6. 后置处理器 BeanPostProcessors 执行
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException;
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException; // 7.
<T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException; // 8. 属性注入时根据类型查找依赖,支持 List<BeanA> list 集合类型注入
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName)
throws BeansException;
Object resolveDependency(DependencyDescriptor descriptor, String beanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException;
}

总结一下:

  1. 首先几个属性,是装配策略:

    • AUTOWIRE_BY_NAME:把与 Bean 的属性具有相同的名字的其他 Bean 自动装配到这个属性上。举个例子就是:当有一个属性名字为 person 时,则自动装配策略选择 id 为 person 的 Bean 进行装配。
    • AUTOWIRE_BY_TYPE:把与 Bean 的属性具有相同的类型的其他 Bean 自动装配到这个属性。
    • AUTOWIRE_BY_CONSTRUCT:把与 bean 的构造器入参具有相同类型的其他 Bean 自动装配到 Bean 构造器的对应参数中。
  2. 还有两类方法,实际上工作中很少直接用这几个接口

    • Typical methods for creating and populating external bean instances,该类是用来根据典型方法默认创建 Bean 和装配 Bean 的方法。
    • Specialized methods for fine-grained control over the bean lifecycle,该类是用来根据装配策略细化装配,具体控制 Bean 生命周期的方法。

实现类为 AbstractAutowireCapableBeanFactory。还有两个配置的接口 ConfigurableBeanFactory 和 ConfigurableListableBeanFactory 也需要关注一下。

五、ConfigurableBeanFactory 配置 BeanFactory

public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {
String SCOPE_SINGLETON = "singleton";
String SCOPE_PROTOTYPE = "prototype"; // 1. 父工厂
void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException; // 2. ClassLoader
void setBeanClassLoader(@Nullable ClassLoader beanClassLoader);
ClassLoader getBeanClassLoader(); void setTempClassLoader(@Nullable ClassLoader tempClassLoader);
ClassLoader getTempClassLoader(); // 3. 缓存
void setCacheBeanMetadata(boolean cacheBeanMetadata);
boolean isCacheBeanMetadata(); // 4. Spring el 表达式解析器
void setBeanExpressionResolver(@Nullable BeanExpressionResolver resolver);
BeanExpressionResolver getBeanExpressionResolver(); // 5.1 ConversionService 类型转换
void setConversionService(@Nullable ConversionService conversionService);
ConversionService getConversionService(); // 5.2 PropertyEditor 类型转换
void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);
void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);
void copyRegisteredEditorsTo(PropertyEditorRegistry registry); // 5.3 类型转换
void setTypeConverter(TypeConverter typeConverter);
TypeConverter getTypeConverter(); // 6. ${key} 占位符解析
void addEmbeddedValueResolver(StringValueResolver valueResolver);
boolean hasEmbeddedValueResolver();
String resolveEmbeddedValue(String value); // 7. 后置处理器
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
int getBeanPostProcessorCount(); // 8.
void registerScope(String scopeName, Scope scope);
String[] getRegisteredScopeNames();
Scope getRegisteredScope(String scopeName); AccessControlContext getAccessControlContext(); // 9. copy 配置
void copyConfigurationFrom(ConfigurableBeanFactory otherFactory); // 10. bean 别名注册
void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException;
void resolveAliases(StringValueResolver valueResolver); // 11. BeanDefinition
BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; // 12. FactoryBean
boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException; // 13. bean 创建状态
void setCurrentlyInCreation(String beanName, boolean inCreation);
boolean isCurrentlyInCreation(String beanName); // 14. 注册依赖
void registerDependentBean(String beanName, String dependentBeanName);
String[] getDependentBeans(String beanName);
String[] getDependenciesForBean(String beanName); // 15. 销毁 bean
void destroyBean(String beanName, Object beanInstance);
void destroyScopedBean(String beanName);
void destroySingletons();
}

实现类为 AbstractBeanFactory。

六、ConfigurableListableBeanFactory 集大成者

提供解析,修改 bean定义,并与初始化单例。

public interface ConfigurableListableBeanFactory
extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory { // 1. 忽略依赖检查,如 String/BeanFacory
void ignoreDependencyType(Class<?> type);
void ignoreDependencyInterface(Class<?> ifc); // 2. 注册依赖关系
void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue); // 3. 依赖注入时查找是否是可以依赖的 bean
boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
throws NoSuchBeanDefinitionException; // 4. BeanDefinition 和 bean 遍历
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
Iterator<String> getBeanNamesIterator(); // 5. 清除不能缓存的 BeanDefinition,当 configurationFrozen=true 时可以缓存
void clearMetadataCache();
// 5.2 configurationFrozen=true 时缓存 BeanDefinition 信息
void freezeConfiguration();
boolean isConfigurationFrozen(); // 6. 实例化非懒加载的 bean
void preInstantiateSingletons() throws BeansException;
}

实现类为 DefaultListableBeanFactory。

此外 Spring BeanFactory 的实现还有三个重要的实现类,功能如下:

  • AbstractBeanFactory 实现了 BeanFactory、 HierarchicalBeanFactory、ConfigurableBeanFactory 三个接口,最重要的方法是实现了 getBean(beanName) 接口,这个方法的最重要的步骤-创建 bean 则委托给模板方法 createBean 完成。

  • AbstractAutowireCapableBeanFactory 实现了 AutowireCapableBeanFactory 接口,也就是依赖注入。同时实现了 crcreateBean(beanName, mbd, args) 创建 bean 的三个重要过程:实例化(createBeanInstance)、依赖注入(populateBean)、初始化(initializeBean)。其中依赖注入又分为 autowireByName 和 autowireByType 二种,其中名称查找很简单,而类型查找就复杂了很多。Spring 将类型查找委托给了子类的 resolveDependency 完成。

  • DefaultListableBeanFactory 实现了 ConfigurableListableBeanFactory、BeanDefinitionRegistry 两个接口,提供了 Bean 和 BeanDefinition 查找注册的功能。 这个类一个很重要的功能是实现了模板方法 resolveDependency,这样就可以根据类型查找依赖。


每天用心记录一点点。内容也许不重要,但习惯很重要!

Spring IOC(一)体系结构的更多相关文章

  1. Spring之一:IoC容器体系结构

    温故而知心. Spring IoC概述 常说spring的控制反转(依赖反转),看看维基百科的解释: 如果合作对象的引用或依赖关系的管理要由具体对象来完成,会导致代码的高度耦合和可测试性降低,这对复杂 ...

  2. 【初探Spring】------Spring IOC(三):初始化过程---Resource定位

    我们知道Spring的IoC起到了一个容器的作用,其中装得都是各种各样的Bean.同时在我们刚刚开始学习Spring的时候都是通过xml文件来定义Bean,Spring会某种方式加载这些xml文件,然 ...

  3. Spring IoC源码解析——Bean的创建和初始化

    Spring介绍 Spring(http://spring.io/)是一个轻量级的Java 开发框架,同时也是轻量级的IoC和AOP的容器框架,主要是针对JavaBean的生命周期进行管理的轻量级容器 ...

  4. 谈谈对Spring IOC的理解(转)

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  5. spring ioc 源码解析

    什么是ioc? 通俗的解释是:(spring)框架中,完成对象的创建和注入的容器. springIOC体系结构: spring IOC的创建是典型的工厂模式,这一系列的bean工厂如上所示. 其核心是 ...

  6. Spring:源码解读Spring IOC原理

    Spring IOC设计原理解析:本文乃学习整理参考而来 一. 什么是Ioc/DI? 二. Spring IOC体系结构 (1) BeanFactory (2) BeanDefinition 三. I ...

  7. 谈谈对Spring IOC的理解

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  8. Spring系列之谈谈对Spring IOC的理解

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IOC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  9. 谈谈对Spring IOC的理解【转】

    学习过Spring框架的人 一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大 ...

随机推荐

  1. The <classpath> or <modulepath> for <junit> must include junit.jar if not in Ant's own classpath

    The <classpath> or <modulepath> for <junit> must include junit.jar if not in Ant's ...

  2. STOP OUR NEGATIVE THOUGHTS

    Do you ever feel like you're in over your head and at any moment you're going to burst? You're not a ...

  3. 【C++】STL算法之remove_if

    之前写过这样一段代码: auto iter=remove_if(AllEdges.begin(),AllEdges.end(),[&](Edge* edge){return _isEedge( ...

  4. python--第二天总结

    一.作用域只要变量在内存中存在,则就可以使用.(栈) 二.三元运算result = 值result = 值1 if 条件 else 值2 如果条件为真:result = 值1如果条件为假:result ...

  5. SQLdeveloper换成windows主题后不显示的情况

    这几天因为换电脑需要重新安装数据库, 因为换成了64位系统, 原先的oracle数据库也换成了64位, 但是plsql还是要用32位的, 经过深思熟虑也没装, 请教了一个同学改用oracle自带的sq ...

  6. node搭建简单的本地服务器

    首先要安装node,方法很多,可以去网上找找,可以直接去官网下载安装,新版本的node是自带npm的: 安装好以后,新建一个js文件,名为server.js: let http = require(' ...

  7. 牛客网Wannafly挑战赛15 B车辆安排(模拟)AND C 出队(规律)

    传送门 :B题:点我 C题: 点我 题目描述 有n个队伍,每个队伍的人数小于等于5,每辆车最多坐5个人,要求一个队伍的人都在一辆车上,求最少的车数 输入描述: 第一行n第二行n个数,表示每个队伍的人数 ...

  8. 9. Palindrome Number (考虑负数的情况)

    Determine whether an integer is a palindrome. Do this without extra space. long int reverse(int x) { ...

  9. @RequestParam使用须知

    --------------------------siwuxie095                             @RequestParam 使用须知         使用 @Requ ...

  10. vue-webpack项目自动打包压缩成zip文件批处理

    为什么需要这个? 使用vue框架开发项目,npm run build这个命令会一直用到,如果需要给后端发包,那你还要打包成zip格式的压缩包,特别是项目提测的时候,一天可能要执行重复好几次,所以才有了 ...