大话Spring(二) --- 再探IoC之BeanFactory

上士闻道,勤而行之;中士闻道,若存若亡;下士闻道,大笑之。

不笑不足以为道。

故建言有之:明道若昧;进道若退;夷道若颣;上德若谷,大白若辱,广德若不足,建德若偷,质真若渝;大方无隅;大器晚成;大音希声;大象无形。

道隐无名。

夫唯道,善始且善成。        ---道德经

 


BeanFactory

我们知道,Spring的IoC容器是一个IoC Service Provider,是一个提供IoC支持的轻量级容器,也就是说,除了基本的IoC支持,还提供了相应的AOP框架的支持、企业级服务集成等服务

BeanFactoryApplicationContext是Spring提供的两种容器类型

BeanFactory只是一个接口类,顾名思义,就是生产Bean的工厂,在Spring中,把每个业务对象都看作一个JavaBean对象,BeanFactory的工作就包括了业务对象的注册和对象间依赖关系的绑定。

  1 //BeanFactory 源码
  2 package org.springframework.beans.factory;
  3 /**
  4 spring ioc 的核心接口,从配置资源(eg: XML)中加载Bean定义并提供对Bean操作的基础方法
  5 Bean:由一个String类型字符串唯一标识的java对象
  6 Bean的作用域(scope):
  7 Singleton:对于某个Bean定义只有一个实例 默认单例,在工厂中全局唯一,只创建一次
  8 Protorype:对于某个Bean定义存在多个实例 全局不唯一 每次使用都会创建一个新的对象
  9 
 10 本接口中的方法支持分层结构,也就是说对于继承了HierarchicalBeanFactory的Factory,可以使用本接口
 11 中的方法找到父工厂中的Bean,如Bean同名则覆盖
 12 
 13 支持使用Aware接口
 14 */
 15 public interface BeanFactory {
 16 /**
 17     获取类型为FactoryBean的对象时,在BeanName前加上&会获取到该对象本身的引用,
 18     否则会获取调用该对象的getObject方法
 19 */
 20     String FACTORY_BEAN_PREFIX = "&";
 21 
 22 /**
 23     返回指定BeanName(或别名)的Bean
 24     对Protorype:每次返回不同的实例
 25     对Singleton:每次返回相同的实例
 26 */
 27     Object getBean(String name) throws BeansException;
 28 
 29 /**
 30     返回同时匹配指定BeanName(或别名)和类型的Bean
 31     对Protorype:每次返回不同的实例
 32     对Singleton:每次返回相同的实例
 33 */
 34     <T> T getBean(String name, Class<T> requiredType) throws BeansException;
 35 
 36 /**
 37     返回指定BeanName(或别名)的Bean,并把所提供的参数作为构造函数参数或工厂方法参数初始化Bean
 38     对Protorype:每次返回不同的实例
 39     对Singleton:抛出BeanDefinitionStoreException异常
 40 */
 41     Object getBean(String name, Object... args) throws BeansException;
 42 
 43 /**
 44     返回指定类型的Bean,如果存在多个bean定义有相同的类型,则抛NoUniqueBeanDefinitionException异常
 45     对Protorype:每次返回不同的实例
 46     对Singleton:每次返回相同的实例
 47 */
 48     <T> T getBean(Class<T> requiredType) throws BeansException;
 49 
 50 /**
 51     返回指定类型的Bean,并把所提供的参数作为构造函数参数或工厂方法参数初始化Bean
 52     对Protorype:每次返回不同的实例
 53     对Singleton:抛出BeanDefinitionStoreException异常
 54 */
 55     <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
 56 
 57 /**
 58     返回一个ObjectProvider<T>该类型允许对Bean处于not available情况和not-unique情况时做处理
 59 */
 60     <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
 61 
 62 /**
 63     作用同上
 64 */
 65     <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
 66 
 67 /**
 68     根据指定的BeanName或别名判断factory是否包含bean定义(concrete
 69      or abstract, lazy or eager, in scope or not)或由外部注册的单例,
 70     返回true时并不保证一定能通过getBean获取相应实例(eg: 抽象Bean)
 71 */
 72     boolean containsBean(String name);
 73 
 74 /**
 75     根据指定的BeanName或别名判断factory中该Bean的scope是否是Singleton
 76     返回false时不代表scope是prototype(使用自定义的scope时)
 77 */
 78     boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
 79 
 80 /**
 81     根据指定的BeanName或别名判断factory中该Bean的scope是否是Prototype
 82     返回false时不代表scope是Singleton(使用自定义的scope时)
 83 */
 84     boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
 85 
 86 /**
 87     根据指定的BeanName或别名判断factory中该Bean的类型是否与提供的类型匹配
 88 */
 89     boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
 90 
 91 /**
 92     根据指定的BeanName或别名判断factory中该Bean的类型是否与提供的类型匹配
 93 */
 94     boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
 95 
 96 /**
 97     根据指定的BeanName或别名获取factory中该Bean的类型,对于FactoryBean类型,将调用它的
 98     getObjectType()
 99 */
100     @Nullable
101     Class<?> getType(String name) throws NoSuchBeanDefinitionException;
102 
103 /**
104     根据指定的BeanName或别名返回factory中该Bean的别名,
105     如果提供的时别名将返回BeanName和其他别名的数组,BeanName
106     置与第一个元素
107 */
108     String[] getAliases(String name);
109 
110 }

BeanFactory 是顶级接口,定义了IOC容器最基本的形式,
 对于左边部分,则是各种功能的BeanFactory,右边部分则是对BeanDefinition的功能操作,中间部分则是单例Bean功能服务

基本上,BeanFactory接口只定义如何访问容器内管理的Bean的方法,各个BeanFactory的具体实现类负责具体Bean的注册以及管理工作

 

从功能的方面简单地说

ListableBeanFactory定义了的一个可列举(迭代)的BeanFactory,通过这个BeanFactory 可以查找特定的Bean,相比顶级的BeanFactory,其查询更加多样化,牵涉到了BeanDefinition,BeanName,注解。

HierarchicalBeanFactory为分层式的BeanFactory,这个工厂接口非常简单,实现了Bean工厂的分层。相对于BeanFactory接口,它只扩展了一个重要的功能——工厂分层,可以指定父工厂(容器),同时查找bean的时候,可以只查找本容器,忽略父容器。

AutowireCapableBeanFactory ,这个BeanFactory 增加了注解功能,可以通过注解进行装配(操作)的工厂(容器)。

上面三个 Factory 是 BeanFactory 接口的直系亲属,三种不同样式的BeanFactory ,分层容器,可列举(查询)容器,自动装配容器,职能单一原则

ListableBeanFactory(可列举的容器(多花样查询)),HierarchicalBeanFactory(分层次容器,可有父容器),AutowireCapableBeanFactory(自动装配容器),这三个容器定义了BeanFactory的基本面貌,在这个三个直系亲属下面又派生了两个复杂的容器:ConfigurableBeanFactory,ConfigurableListableBeanFactory,可配置的(可操作)的容器,通过这两个BeanFactory 可有修改容器中的bean,功能又更加高级了,集成了单例bean 服务,以及BeanDefinition 注册服务,那么对于 DefaultListableBeanFactory 来说,此时它就是一个可注册,可配置,可获取的BeanFactory ,就容器方面而言功能已经健全了。

 


配置文件

 

 

三种注入方式


  • 八种基本类型 + String类型 + 日期类型的注入  value
  • 引用对象  ref

Set方式

getter/setter注入

a.类中的属性,必须有getter/setter方法;
b.在bean中,通过property来完成对响应属性的注入;

 


构造注入

a.要求类中,必须有对应的构造方法存在(可以没有getter/setter方法);
b.要按照构造参数的顺序,利用constructor-arg标签,逐个为参数注入;
在constructor-arg标签中,也可以添加一些属性;
index:注入到第几个参数中,从0开始数;
name:注入到指定名字的参数中;
type:注入到指定类型的参数中;

 

接口注入

    • byName:被注入bean的id名必须与set方法后半截匹配,并且id名称的第一个单词首字母必须小写,这一点与手动set注入有点不同。

    • byType:查找所有的set方法,将符合符合参数类型的bean注入。

无论使用以上哪种方式注入都需要为属性提供set方法

posted @ 2020-08-08 23:31  CodePrince86  阅读(105)  评论(0)    收藏  举报