Spring源码解析 - BeanFactory接口体系解读

不知道为什么看着Spring的源码,感触最深的是Spring对概念的抽象,所以我就先学接口了.

BeanFactory是Spring IOC实现的基础,这边定义了一系列的接口,我们通过这些接口的学习,可以大致了解BeanFactory体系各接口如何分工合作.

为学习具体实现打下基础.毕竟这边逻辑复杂,涉及的概念很多.

BeanFactory 是Spring bean容器的根接口.提供获取bean,是否包含bean,是否单例与原型,获取bean类型,bean 别名的api.

-- AutowireCapableBeanFactory 添加集成其他框架功能.如果集成WebWork则可以使用Spring对Actions等进行管理.

-- HierarchicalBeanFactory 提供父容器的访问功能

-- -- ConfigurableBeanFactory 如名,提供factory的配置功能,眼花缭乱好多api

-- -- -- ConfigurableListableBeanFactory 集大成者,提供解析,修改bean定义,并与初始化单例.

-- ListableBeanFactory 提供容器内bean实例的枚举功能.这边不会考虑父容器内的实例.

看到这边,我们是不是想起了设计模式原则里的接口隔离原则

Interface Segregation Principle(ISP):客户端不应该依赖它不需要的接口;类间的依赖关系应该建立在最小的接口上

对这个有兴趣的话,找度娘或者看看这个设计模式六大原则(4):接口隔离原则

这边清晰地定义了如下的体系:

  根接口BeanFactory(基础容器)

  第二层: 第三方集成,继承体系,遍历bean

  第三层: 配置功能

  第四层: 配置+迭代

接下来具体分析下各个接口吧(顺便做目录):

1. BeanFactory

2. AutowireCapableBeanFactory

3. HierarchicalBeanFactory

4. ListableBeanFactory

5. ConfigurableBeanFactory

6. ConfigableListableBeanFactory

1. BeanFactory

BeanFactory是Spring bean容器的根接口.

每个bean都是通过string类型bean name进行标识.这边提供了设计模式单例,原型的替代实现.

  如果bean name配置为单例,应用内只会获取到一个实例.如果配置为原型,那么可以实例化好后填充属性(基于用户的配置).

BeanFactory作为应用集中配置管理的地方,极大简便应用开发,这样开发人员可以集中与业务.

BeanFactory需要管理bean的生命周期,比如初始化时需要按顺序实现如下接口:

  1. BeanNameAware‘s {@code setBeanName}
  2. BeanClassLoaderAware‘s {@code setBeanClassLoader}
  3. BeanFactoryAware‘s {@code setBeanFactory}
  4. ResourceLoaderAware‘s {@code setResourceLoader}仅对application context有效
  5. ApplicationEventPublisherAware‘s {@code setApplicationEventPublisher}仅对application context有效
  6. MessageSourceAware‘s {@code setMessageSource}仅对application context有效
  7. ApplicationContextAware‘s {@code setApplicationContext}仅对application context有效
  8. ServletContextAware‘s {@code setServletContext}仅对application context有效
  9. {@code postProcessBeforeInitialization} methods of BeanPostProcessors
  10. InitializingBean‘s {@code afterPropertiesSet}
  11. a custom init-method definition xml中配置的init-method
  12. {@code postProcessAfterInitialization} methods of BeanPostProcessors

还有关闭容器的接口:

  1. DisposableBean‘s {@code destroy}
  2. a custom destroy-method definition xml配置中的destroy-method

接口里定义了一个变量String FACTORY_BEAN_PREFIX = "&";

  这是用来区分是获取FactoryBean还是FactoryBean的createBean创建的实例.如果&开始则获取FactoryBean;否则获取createBean创建的实例.

我们来看下定义的方法:

  a, 获取bean,这边可以实现单例,原型

    Object getBean(String name) throws BeansException; 可以用别名查找哦

    <T> T getBean(String name, Class<T> requiredType) throws BeansException;

    <T> T getBean(Class<T> requiredType) throws BeansException; 这边的类型可以是接口或者子类,但不能是null

    Object getBean(String name, Object... args) throws BeansException;

  b, 判断是否包含bean.陷阱出现:这边不管类是否抽象类,懒加载,是否在容器范围内,只要符合都返回true,所以这边true,不一定能从getBean获取实例

    boolean containsBean(String name);

  c, 单例,原型,bean类型的判断

    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;

  d, 获取bean 的类型,别名

    Class<?> getType(String name) throws NoSuchBeanDefinitionException;

    String[] getAliases(String name);

2. AutowireCapableBeanFactory

在BeanFactory基础上实现对已存在实例的管理.

可以使用这个接口集成其它框架,捆绑并填充并不由Spring管理生命周期并已存在的实例.像集成WebWork的Actions 和Tapestry Page就很实用.

一般应用开发者不会使用这个接口,所以像ApplicationContext这样的外观实现类不会实现这个接口,如果真手痒痒可以通过ApplicationContext的getAutowireCapableBeanFactory接口获取.

这边定义了5种自动装配策略:不注入AUTOWIRE_NO,使用bean name策略装配AUTOWIRE_BY_NAME,使用类型装配策略AUTOWIRE_BY_TYPE,使用构造器装配策略AUTOWIRE_CONSTRUCTOR,自动装配策略AUTOWIRE_AUTODETECT

  这边的自动策略是先尝试构造器,然后才是byType.这边应该是跟xml配置文件中的装配策略对应.

继续看定义的api:

  a, 创建和填充外部bean实例的典型方法

    <T> T createBean(Class<T> beanClass) throws BeansException;

    void autowireBean(Object existingBean) throws BeansException; // 使用autowireBeanProperties装配属性

    Object configureBean(Object existingBean, String beanName) throws BeansException; // 自动装配属性,填充属性值,使用诸如setBeanName,setBeanFactory这样的工厂回调填充属性,最好还要调用post processor

    Object resolveDependency(DependencyDescriptor descriptor, String beanName) throws BeansException;

  b, 在bean的生命周期进行细粒度控制的专门方法

    Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException; // 会执行bean完整的初始化,包括BeanPostProcessors和initializeBean

    Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;

    void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck) throws BeansException;

    void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;

    Object initializeBean(Object existingBean, String beanName) throws BeansException;

    Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException;

    Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException;

    Object resolveDependency(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException;

3. HierarchicalBeanFactory

提供父容器的访问功能.至于父容器的设置,需要找ConfigurableBeanFactory的setParentBeanFactory(接口把设置跟获取给拆开了!).

这边可说的不多,直接上api:

  a, 获取父容器 bean factory

    BeanFactory getParentBeanFactory();

  b, 判断当前容器是否保护bean

    boolean containsLocalBean(String name);

4. ListableBeanFactory

获取bean时,Spring 鼓励使用这个接口定义的api. 还有个Beanfactory方便使用.其他的4个接口都是不鼓励使用的.

提供容器中bean迭代的功能,不再需要一个个bean地查找.比如可以一次获取全部的bean(太暴力了),根据类型获取bean.在看SpringMVC时,扫描包路径下的具体实现策略就是使用的这种方式(那边使用的是BeanFactoryUtils封装的api).

如果同时实现了HierarchicalBeanFactory,返回值不会考虑父类BeanFactory,只考虑当前factory定义的类.当然也可以使用BeanFactoryUtils辅助类来查找祖先工厂中的类.

这个接口中的方法只会考虑本factory定义的bean.这些方法会忽略ConfigurableBeanFactory的registerSingleton注册的单例bean(getBeanNamesOfType和getBeansOfType是例外,一样会考虑手动注册的单例).当然BeanFactory的getBean一样可以透明访问这些特殊bean.当然在典型情况下,所有的bean都是由external bean定义,所以应用不需要顾虑这些差别.

注意:getBeanDefinitionCount和containsBeanDefinition的实现方法因为效率比较低,还是少用为好.

继续上api吧

  a, 暴力获取全部bean的属性:

    boolean containsBeanDefinition(String beanName);  //是否包含bean

    int getBeanDefinitionCount(); // 当前factory中定义的bean数量

    String[] getBeanDefinitionNames(); // 获取当前工厂中定义的所有bean 的name

  b, 根据bean 的类型获取bean

    这边的方法仅检查顶级bean.它不会检查嵌套的bean.FactoryBean创建的bean会匹配为FactoryBean而不是原始类型.

    一样不会考虑父factory中的bean,非要用可以通过BeanFactoryUtils中的beanNamesForTypeIncludingAncestors.
    其他方式注册的单例这边会纳入判断.
    这个版本的getBeanNamesForType会匹配所有类型的bean,包括单例,原型,FactoryBean.返回的bean names会根据backend 配置的进行排序.

    String[] getBeanNamesForType(Class<?> type); // 获取给定类型的bean names(包括子类),通过bean 定义或者FactoryBean的getObjectType判断.

    String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);

    <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException; // 如果保护懒加载的类,FactoryBean初始化的类和工厂方法初始化的类会被初始化.就是说执行这个方法会执行对应的初始化.

    <T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException;

  c, 查找使用注解的类

    Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;

  d, 查找一个类上的注解,如果找不到,父类,接口使用注解也算.

    <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType);

5. ConfigurableBeanFactory

定义BeanFactory的配置.

这边定义了太多太多的api,比如类加载器,类型转化,属性编辑器,BeanPostProcessor,作用域,bean定义,处理bean依赖关系,合并其他ConfigurableBeanFactory,bean如何销毁.

定义了两个作用域: 单例和原型.可以通过registerScope来添加.

  SCOPE_SINGLETON,SCOPE_PROTOTYPE

这边定义了好多好多的api,所以我们这边只讲业务,具体的api看文末的附录吧:

  a, 父容器设置.而且一旦设置了就不让修改

  b, 类加载器设置与获取.默认使用当前线程中的类加载器

  c, 为了类型匹配,搞个临时类加载器.好在一般情况为null,使用上面定义的标准加载器  

  d, 是否需要缓存bean metadata,比如bean difinition 和 解析好的classes.默认开启缓存

  e, 定义用于解析bean definition的表达式解析器

  f, 类型转化器

  g, 属性编辑器

  h, BeanFactory用来转换bean属性值或者参数值的自定义转换器

  i,string值解析器(想起mvc中的ArgumentResolver了)

  j,大boss BeanPostProcessor用于增强bean初始化功能 

  k,作用域定义

  l,访问权限控制

  m, 合并其他ConfigurableBeanFactory的配置,包括上面说到的BeanPostProcessor,作用域等

  n, bean定义处理

  o, bean创建状态控制.在解决循环依赖时有使用

  p, 处理bean依赖问题

  q, bean生命周期管理-- 销毁bean

6. ConfigableListableBeanFactory

提供bean definition的解析,注册功能,再对单例来个预加载(解决循环依赖问题).

貌似我们一般开发就会直接定义这么个接口了事.而不是像Spring这样先根据使用情况细分那么多,到这边再合并

  a, 设置忽略的依赖关系,注册找到的特殊依赖

    void ignoreDependencyType(Class<?> type); // 忽略类型

    void ignoreDependencyInterface(Class<?> ifc); // 忽略接口

    void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue);

    boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor) throws NoSuchBeanDefinitionException;

  b, 获取bean定义 (可以访问属性值跟构造方法的参数值)

    BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

  c, 锁定配置信息.在调用refresh时会使用到.

    void freezeConfiguration();

    boolean isConfigurationFrozen();

  d, 预加载不是懒加载的单例.用于解决循环依赖问题

    void preInstantiateSingletons() throws BeansException;

附录--ConfigureableBeanFactory中定义的api:

  a, 父容器设置.而且一旦设置了就不让修改

    void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;

  b, 类加载器设置与获取.默认使用当前线程中的类加载器

    void setBeanClassLoader(ClassLoader beanClassLoader);

    ClassLoader getBeanClassLoader();

  c, 为了类型匹配,搞个临时类加载器.好在一般情况为null,使用上面定义的标准加载器  

    void setTempClassLoader(ClassLoader tempClassLoader);

    ClassLoader getTempClassLoader();

  d, 是否需要缓存bean metadata,比如bean difinition 和 解析好的classes.默认开启缓存

    void setCacheBeanMetadata(boolean cacheBeanMetadata);

    boolean isCacheBeanMetadata();

  e, 定义用于解析bean definition的表达式解析器

    void setBeanExpressionResolver(BeanExpressionResolver resolver);

    BeanExpressionResolver getBeanExpressionResolver();

  f, 类型转化器

    void setConversionService(ConversionService conversionService);

    ConversionService getConversionService();

  g, 属性编辑器

    void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);

    void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);

    void copyRegisteredEditorsTo(PropertyEditorRegistry registry);

  h, BeanFactory用来转换bean属性值或者参数值的自定义转换器

    void setTypeConverter(TypeConverter typeConverter);

    TypeConverter getTypeConverter();

  i,string值解析器(想起mvc中的ArgumentResolver了)

    void addEmbeddedValueResolver(StringValueResolver valueResolver);

    String resolveEmbeddedValue(String value);

  j,大boss BeanPostProcessor用于增强bean初始化功能

    void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);

    int getBeanPostProcessorCount();    

  k,作用域定义

    void registerScope(String scopeName, Scope scope);

    String[] getRegisteredScopeNames();

    Scope getRegisteredScope(String scopeName);

  l,访问权限控制

    AccessControlContext getAccessControlContext();

  m, 合并其他ConfigurableBeanFactory的配置,包括上面说到的BeanPostProcessor,作用域等

    void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);

  n, bean定义处理

    void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException; // 注册别名

    void resolveAliases(StringValueResolver valueResolver);

    BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; // 合并bean定义,包括父容器的

    boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException; // 是否是FactoryBean类型

  o, bean创建状态控制.在解决循环依赖时有使用

    void setCurrentlyInCreation(String beanName, boolean inCreation);

    boolean isCurrentlyInCreation(String beanName);

  p, 处理bean依赖问题

    void registerDependentBean(String beanName, String dependentBeanName);

    String[] getDependentBeans(String beanName);

    String[] getDependenciesForBean(String beanName);

  q, bean生命周期管理-- 销毁bean

    void destroyBean(String beanName, Object beanInstance);

    void destroyScopedBean(String beanName);

    void destroySingletons();

时间: 2024-10-27 06:54:04

Spring源码解析 - BeanFactory接口体系解读的相关文章

Spring源码解析 - BeanFactory

BeanFactory是Spring实现依赖注入的核心接口.提供应用的统一配置注册功能,实现业务开发解偶.使用getBean可以代替单例,原型设计模式. 顶重要的BeanFactory里注释写得太好了.所以咱们先翻译下注释,后面再详细分析. 重点直接看红色标注吧. The root interface for accessing a Spring bean container. This is the basic client view of a bean container; further

Spring源码分析——BeanFactory体系之抽象类、类分析(一)

上一篇介绍了BeanFactory体系的所有接口——Spring源码分析——BeanFactory体系之接口详细分析,本篇就接着介绍BeanFactory体系的抽象类和接口. 一.BeanFactory的基本类体系结构(类为主): 上图可与 Spring源码分析——BeanFactory体系之接口详细分析 的图结合分析,一个以接口为主,一个以类为主(PS:Spring的体系结构要分析清楚,不得不曲线救国啊!不然27寸屏幕给我画估计都装不下.). 具体: 1.7层的类体系继承. 2.Abstrac

Spring源码分析——BeanFactory体系之抽象类、类分析(二)

上一篇分析了BeanFactory体系的2个类,SimpleAliasRegistry和DefaultSingletonBeanRegistry——Spring源码分析——BeanFactory体系之抽象类.类分析(一),今天继续分析. 一.工厂Bean注册支持——FactoryBeanRegistrySupport 废话不多说,直接看我注释的源码: /* * Copyright 2002-2012 the original author or authors. * * Licensed und

软件开发工程师(JAVA)中级考试大纲--spring源码解析

spring源码解析(1)----IOC 一.IOC容器 在Spring中,IOC容器的重要地位我们就不多说了,对于Spring的使用者而言,IOC容器实际上是什么呢?我们可以说BeanFactory就是我们看到的IoC容器,当然了Spring为我们准备了许多种IoC容器来使用,这样可以方便我们从不同的层面,不同的资源位置,不同的形式的定义信息来建立我们需要的IoC容器. 在Spring中,最基本的IOC容器接口是BeanFactory - 这个接口为具体的IOC容器的实现作了最基本的功能规定 

Spring 源码解析之HandlerAdapter源码解析(二)

Spring 源码解析之HandlerAdapter源码解析(二) 前言 看这篇之前需要有Spring 源码解析之HandlerMapping源码解析(一)这篇的基础,这篇主要是把请求流程中的调用controller流程单独拿出来了 解决上篇文章遗留的问题 getHandler(processedRequest) 这个方法是如何查找到对应处理的HandlerExecutionChain和HandlerMapping的,比如说静态资源的处理和请求的处理肯定是不同的HandlerMapping ge

Spring 源码解析之ViewResolver源码解析(四)

Spring 源码解析之ViewResolver源码解析(四) 1 ViewResolver类功能解析 1.1 ViewResolver Interface to be implemented by objects that can resolve views by name. View state doesn't change during the running of the application, so implementations are free to cache views. I

Spring 源码解析之DispatcherServlet源码解析(五)

Spring 源码解析之DispatcherServlet源码解析(五) 前言 本文需要有前四篇文章的基础,才能够清晰易懂,有兴趣可以先看看详细的流程,这篇文章可以说是第一篇文章,也可以说是前四篇文章的的汇总,Spring的整个请求流程都是围绕着DispatcherServlet进行的 类结构图 根据类的结构来说DispatcherServlet本身也是继承了HttpServlet的,所有的请求都是根据这一个Servlet来进行转发的,同时解释了为什么需要在web.xml进行如下配置,因为Spr

SPRING源码解析-SPRING 核心-IOC

IoC 和 AOP是Spring的核心, 是Spring系统中其他组件模块和应用开发的基础.透过这两个模块的设计和实现可以了解Spring倡导的对企业应用开发所应秉承的思路: 易用性. POJO开发企业应用, 直接依赖于Java语言,而不是容器和框架. 提升程序的可测试性,提高软件质量. 提供一致性编程模型,面向接口的编程 降低应用的负载和框架的侵入性.IoC和AOP实现. 不作为现有解决方案的替代,而是集成现有. IoC和AOP这两个核心组件,特别是IoC容器,使用户在使用Spring完成PO

[原创]spring源码解析-- 定义Advice接口的作用和意图

Spring在包org.aopalliance.aop下定义了Advice接口,该接口没有任何方法和属性: public interface Advice { } 那么Spring定义该接口的意图是什么呢?该接口的作用是什么呢?针对这些问题,我会不断通过研究Spring源码,持续更新最新的发现.