Spring4--在IoC容器中装配Bean

背景

本章的重点是介绍如何装配Bean。

1.Spring配置概述

Bean配置信息是Bean的元数据信息,它由四个方面组成:

(1)Bean的实现类;

(2)Bean的属性信息,如数据源的连接数、用户名、密码等;

(3)Bean的依赖关系,Spring根据依赖关系配置完成Bean之间的装配;

(4)Bean的行为配置,如生命周期范围及生命周期各过程的回调函数等。

Bean元数据信息在Spring容器中的内部对应物是由BeanDefinition形成的Bean注册表。

下面这张图描述了Spring容器、Bean配置信息、Bean实现类及应用程序之间的相互关系:

基于xml的配置,spring采用Schema格式。spring配置的Schema文件放置在各模块JAR文件内一个名为config的目录下。

2.依赖注入

(1)属性注入指通过setXxx()方法注入Bean的属性值或依赖对象。Spring只会检查Bean中是否有对应的Setter方法,至于

Bean中是否有对应的属性成员变更则不做要求。Spring配置文件中<property>元素所指定的属性名和Bean实现类的Setter

方法满足Sun JavaBean的属性命名规范:xxx的属性对应 setXxx()方法。JavaBean的变量的前两个字母要么全部大写,要

么全部小写。

(2)构造函数注入,它能保证一些必要的属性在Bean实例化就得到设置,确保Bean实例化后就可以使用。Spring容器能对构

造函数配置的Bean进行实例化的前提是,即构造函数入参引用的对象必须已经准备就绪。如果两个Bean都采用构造函数注入,

而且都通过构造函数入参引用对方,就会发生类似于线程死锁的循环依赖问题。解决办法是修改Bean的代码,将构造函数注入

方式调整为属性注入方式。

(3)工厂方法注入。Spring IoC容器以框架的方式提供工厂方法的功能,并以透明的方式开放给开发者,所以很少需要手工编写

基于工厂方法的类。

3.注入参数详解

(1)字面值,指可用字符串表示的值,这些值可以通过<value>元素标签进行注入。Spring容器在内部为字面值提供了编辑器,

它可以将以字符串表示的字面值转换为内部变量的相应类型。

如果配置文件中的注入值包括下面的特殊字符,可以采用<![CDATA[]]>特殊标签,将包含特殊字符的字符串封装起来,另一个

办法是使用xml转义序列表示特殊字符。

(2)引用其他Bean,<ref>元素可以通过下面3个属性引用容器中的其他Bean:

1.bean:通过该属性可以引用同一容器或父容器中的Bean;

2.local:通过该属性只能引用同一配置文件中定义的Bean;

3.parent:引用父容器中的Bean。

(3)内部Bean,没有名字,不能被其他Bean引用,只能在声明处为外部Bean提供实例注入。

(4)null值,必须使用专用的<null/>元素标签。

(5)级联属性。

(6)集合类型属性,List、Set、Map、Properties。可以通过util命名空间配置集合类型的Bean。

(7)简化配置方式:

字面值属性简化:

引用对象属性:<ref local="xxx">和<ref parent="xxx">没有对应的简化形式

使用P命名空间:为了简化xml文件的配置,越来越多的xml文件采用属性而子元素配置信息。通过<bean>元素属性的方式配置

Bean的属性。

对于字面值属性  p:<属性名>=“xxx”  ;  对于引用对象的属性  p:<属性名>-ref="xxx"

由于p命名空间的属性名师可变的,所以p命名空间没有对应的Schema定义文件。

(8)自动装配,Spring IoC容器可以按照某种规则对容器中的Bean进行自动装配,而无须通过显式的方式进行依赖配置。<bean>

元素提供了一个指定自动装配类型的属性 autowire="<自动装配类型>"。Spring提供了四种自动装配类型:

<beans>元素标签中的default-autowire属性可以配置全局自动匹配,默认值为no,表示不启用自动装配。

在实际开发中,xml配置方式很少启用自动装配功能,而基于注解的配置方式默认采用byType自动装配策略。

4.方法注入

Spring IoC容器拥有复写Bean方法的能力,归功于CGLib类包。CGLib可以在运行期动态操作Class字节码,为Bean动态

创建子类或实现类。lookup方法注入使用范围,一般是希望通过一个singleton Bean 获取一个prototype Bean时使用。

方法替换,可以使用某个Bean的方法去替换另一个Bean的方法,具体怎么操作看书。

5.<bean>之间的关系

(1)继承,如果多个<bean>存在相同的配置信息,则Spring允许定义一个父<bean>,子<bean>将自动继承父<bean>的配置

信息。父<bean>声明为abstract="true",子<bean>用parent="xxx"指定父<bean>。

(2)依赖,使用<ref>元素标签建立对其他Bean的依赖关系。通过depends-on属性显式制定Bean前置依赖的Bean,前置依赖

Bean会在本Bean实例化之前创建好。

(3)引用,一个<bean>引用另一个<bean>的id属性值,目的是在运行期通过getBean(beanName)方法获取对应的Bean。通过

使用 <idref>元素标签,在容器启动时,Spring会检查引用关系的正确性,这样就可以提前发现错误。

6.整合多个配置文件

在启动Spring容器时,可以通过一个String数组指定这些配置文件,Spring还允许通过<import>将多个配置文件引入到一个文

件中,进行配置文件的集成。

7.Bean作用域

Bean作用域类型:

通过scppe="<作用域类型>" 来指定。还可以自定义Bean的作用域,不过这个比较少用。

(1)singleton,无状态或者状态不可变的类适合使用单例模式。

 如果不希望容器在启动时提前实例化singleton的Bean,可以通过lazy-init属性进行控制。

(2)prototype,在默认情况下,Spring容器在启动时不实例化prototype的Bean。Spring容器将prototype的Bean交给调用者后,

就不再管理它的生命周期。

(3)其他三个是与Web应用环境相关的Bean作用域,在使用之前需要在Web容器中进行额外的配置。利用HTTP请求监听器

进行配置。

两个监听器的区别:

ServletContextListener负责监听Web容器启动和关闭的事件,ServletRequestListener监听HTTP请求事件,Web服务器接收

到的每一次请求都会通知该监听器。

(3)如果将Web相关作用域的Bean注入singleton或prototype的Bean中,我们需要是使用SpringAOP创建代理。 

8.FactoryBean

通过实现该工厂类接口定制实例化Bean的逻辑,它隐藏了实例化一些复杂Bean的细节,给上层应用带来了便利。

9.基于注解的配置

(1)除了@Component外,Spring还提供了3个功能基本和@Component等效的注解,分别对应DAO、Service及Web层的Controller进行注解:

1.@Repository:用于对Dao实现类进行标注。

2.@Service:用于对Service实现类进行标注。

3.@Controller:用于对Controller实现类进行标注。

(2)扫描注解定义的Bean,Spring提供了一个context命名空间,它提供了通过扫描类包以应用注解定义Bean的方式。也可以

通过contex定义过滤的规则,把不要的类过滤掉。

(3)自动装配Bean,使用@Autowired进行自动注入。@Autowired默认按类型(byType)配置的方式在容器中查找匹配的Bean。

在对类方法进行标注时,Spring将自动选择匹配入参类型Bean进行注入。建议在方法上标注@Autowired注解,在单元测试时就

比较方便。

10.基于java类的配置

普通的pojo只要标注@Configuration注解,就可以为Spring容器提供Bean定义的信息,每个标注了@Bean的类方法都相当于

提供了一个Bean的定义信息。

11.基于Groovy DSL的配置

这个稍微看一下,以后要用到再详细看。

12.通过编码方式动态添加Bean

(1)通过DefaultListableBeanFactory,可以扩展配置、循环枚举,实现Bean动态注入,除此之外还要实现BeanFactoryPostProcessor接口。

(2)扩展自定义标签,需要经过一下步骤:

1.采用XSD描述自定义标签的元素属性;

2.编写Bean定义的解析器;

3.注册自定义标签解析器;

4.绑定命名空间解析器。

13.不同配置方式比较

Bean不同配置方式的使用场景:

总结

这一章详细地介绍了Bean的配置,受益匪浅。

猜你喜欢

转载自blog.csdn.net/a614528195/article/details/83050415
今日推荐