javascript
《Spring实战》第四版读书笔记 第二章 装配Bean
2019独角兽企业重金招聘Python工程师标准>>>
在Spring中,对象无需自己查找或创建与其所关联的其他对象。相反,容器负责把需要相互协作的对象引用赋予各个对象。
创建应用对象之间协作关系的行为通常称为装配(wiring),这也是依赖注入的本质。
2.1 Spring配置的可选方案
Spring提供了三种主要的装配机制:
- 在XML中进行显式配置;
- 在Java中进行显式配置;
- 隐式的bean发现机制和自动装配。
作者建议尽可能的使用自动装配的机制。显式配置越少越好,当必须要显式配置bean的时候(比如,有些源码不是由你来维护的,而当你需要为这些代码配置bean的时候),推荐使用类型安全并且比XML更加强大的JavaConfig。最后,只有当你想要使用便利的XML命名空间,并且在JavaConfig中没有同样的实现是才应该使用XML。
2.2 自动化装配bean
Spring从两个角度实现自动化装配:
- 组件扫描(component scanning):Spring会自动发现应用上下文中所创建的bean;
- 自动装配(autowiring):Spring自动满足bean之间的依赖。
2.2.1 创建可被发现的bean
在类上使用@Component注解,这个注解表明该类会作为组件类,并告知Spring要为这个类创建bean。
组件扫描默认是不启用的,还需要显式配置一下Spring,从而命令它去寻找带有@Component注解的类并为其创建bean。
@Configuation @ComponentScan public class CDPlayerConfig { }如果没有其他配置,@ComponentScan默认会扫描与配置类相同的包。
如果想使用XML来启用组件扫描,可以使用Spring context命名空间的context:component-scan元素。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:Context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframeword.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="soundsystem"/> </beans>测试组件扫描代码:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes=CDPlayerConfig.class) public class CDPlayerText {@Autowiredprivate CompactDisc cd;@Testpublic void cdShouldNotBeNull() {assertNotNull(cd)} }CDPlayerTest使用了Spring的SpringJUnit4ClassRunner,以便在测试开始的时候自动创建Spring的应用上下文。注解@ContextConfiguration会告诉它需要在CDPlayerConfig中加载配置。
2.2.2 为组件扫描的bean命名
在组件扫描中如果没有明确的设置ID,Spring会根据类名为其指定一个ID。这个bean所给定的ID是首字母变为小写的类名。
如果想为这个bean设置不同的ID,需要将其作为值传递给@Component注解。
@Component("lonelyHeartsClub") public class SgtPeppers implements CompactDisc { }另外一种bean命名方式使用Java依赖注入规范中提供的@Named注解:
@Named("lonelyHeartsClub") public class SgtPeppers implements CompactDisc { }Spring支持将@Named作为@Component注解的替代方案。两者之间由一些细微的差异,但在大多数场景中可以互换。
本书的作者更喜欢@Component。
2.2.3 设置组件扫描的基础包
如果没有为@ComponentScan设置属性,按照默认规则,它会以配置类所在的包作为基础包来扫描逐渐。
如果想扫描不同的包,在@ComponentScan的value属性中指定包名即可。
@Configuraion @ComponentScan("soundsystem") public class CDPlayerConfig{ }如果想更加清晰的表明所设置的是基础包,可以通过basePackages属性进行配置:
@Configuration @ComponentScan(basePackages="soundsystem") public class CDPlayerConfig{}basePackages属性可以设置多个包,赋值一个数组即可:
@Configuration @ComponentScan(basePackages={"soundsystem", "video"}) public class CDPlayerConfig { }除了将包设置为简单的String类型外,@ComponentScan哈提供了另外一种方法,将其指定为包中所包含的类或接口:
@Configuration @ComponentScan(basePackageClasses={CDPlayer.class, DVDPlayer.class}) public class CDPlayerConfig { }2.2.4 通过为bean添加注解实现自动装配
可以在构造器、setter方法、任何方法上使用@Autowired注解,Spring会尝试满足方法参数上所声明的依赖。假如有且只有一个bean匹配依赖需求,那么这个bean将会被装配进来。
如果没有匹配的bean,那么在应用上下文创建的时候会抛出异常。可以将@Autowired的required属性设置为false,此时Spring会尝试自动装配,但是如果没有匹配的bean的话该属性将会为null。
如果有多个bean都满足依赖关系,Spring将会抛出异常。
@Autowired是Spring特有的注解。可以使用@Inject注解替代。
2.3 通过Java代码装配Bean
显式的装配方式有两种:Java和XML。
2.3.1 创建配置类
@Configuration注解表明这个类是一个配置类,该类应该包含在Spring应用上下文中如何创建bean的细节。
2.3.2 声明简单bean
要在JavaConfig中声明bean,需要编写一个方法,这个方法会创建所需类型的实例,然后给这个方法添加@Bean注解。
@Bean注解会告诉Spring这个方法将返回一个对象,该对象要注册为Spring应用上下文中的bean。方法体中包含了最终产生bean实例的逻辑。
默认情况下,bean的ID与方法名一致。如果想为其设置一个不同的名字,可以重命名该方法,也可以通过@Bean的name属性指定。
2.3.3 借助JavaConfig实现注入
在JavaConfig中装配bean的最简单方式就是引用创建bean的方法。在方法上添加了@Bean注解,Spring将会拦截所有对它的调用,并确保直接返回该方法所创建的bean,而不是每次都对其进行实际的调用。
通过调用方法引用bean的方式有点令人困惑。还有一种理解起来更简单的方式:
@Bean public CDPlayer cdPlayer(CompactDisc compactDisc) {return new CDPlayer(compactDisc); }cdPlaye()方法请求一个CompactDisc作为参数,当Spring调用cdPlayer()创建CDPlayer bean的时候,它会自动装配一个CompactDisc到配置方法之中。
通过这种方式引用其他的bean通常是最佳的选择,因为它不会要求将CompactDisc声明到同一个配置类之中。在这里甚至没有要求CompactDisc必须要在JavaConfig中声明,实际上它可以通过组件扫描功能自动发现或者通过XML来进行配置。可以将配置分散到多个配置类、XML文件以及自动扫面和装配bean之中。
2.4 通过XML装配Bean
2.4.1 创建XML配置规范
在XML配置中,要创建一个XML文件,并且要以<beans>元素为根。
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframeword.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context"><!-- 配置详情 --> </beans>2.4.2 声明一个简单的<bean>
<bean>元素类似于JavaConfig中的@Bean注解。
如果没有给定ID,所以这个bean将会根据全限定类名来进行命名。例如“soundsystem.SgtPeppers#0“,其中“#0”是一个计数形式,用来区分相同类型的其他bean。
2.4.3 借助构造器注入初始化bean
构造器注入有两种基本的配置方案可供选择:
- <constructon-arg>元素;
- 使用Spring 3.0 所引入的c-命名空间。
构造器注入bean引用
<bean id="cdPlayer" class="soundsystem.CDPlayer"><constructor-arg ref="compactDisc"/> </bean>c-命名空间的schema:
xmlns:c="http://www.springframework.org/schema/c" <bean id="cdPlayer" class="soundsystem.CDPlayer" c:cd-ref="compactDisc" />属性以c:开头,也就是命名空间的前缀。接下来是要装配的构造器参数名,在此之后是-ref,这是一个命名约定,告诉Spring正在装配的是一个bean应用。
可以使用参数在整个参数列表中的位置来替代参数名:
<bean id="cdPlayer" class="soundsystem.CDPlayer" c:_0-ref="compactDisc" />因为在XML中不允许数字作为属性的第一个字符,因此必须要添加一个下划线作为前缀。
如果只有一个参数,不用标示参数:
<bean id="cdPlayer" class="soundsystem.CDPlayer"c:_-ref="compactDisc" />将字面量注入到构造器中
<bean id="compactDisc"class="soundsystem.BlankDisc"><constructor-arg value="sgt. Pepper" /> </bean>依然使用<constructor-arg>元素进行注入,但是使用了value属性。
<bean id="compactDisc"class="soundsystem.BlankDisc"c:_title="sgt. Pepper"/>使用c-命名空间装配字面量与装配引用的区别在于属性名中去掉了-ref后缀。
装配集合
<constructor-arg>可以将集合装配到构造器参数重,而c-命名空间不能。
可以使用<null/>元素将null传递给构造器。
可以使用<list>元素声明一个列表:
<constructor-arg><list><value>.....</value><value>......</value></list> </constructor-arg><list>元素是<constructor-arg>的子元素,这表明一个包含值的列表将会传递到构造器中。其中<value>元素用来指定列表中的每个元素。
与之类似,可以使用<ref>元素代替<value>,实现bean引用列表的装配。
可以用相同的方式使用<set>元素。<set>和<list>元素的区别不大,无论在哪种情况下,<set>或<list>都可以用来装配List、Set甚至是数组。
2.4.4 设置属性
<property>元素为属性的setter方法所提供的功能与<constructor-arg>元素为构造器提供的功能是一样的。
Spring提供了p-命名空间作为<property>元素的替代方案。p-命名空间的schema:
xmlns:p="http://www.springframework.org/schema/p"util-命名空间所提供的功能之一是util:list元素,它会创建一个列表的bean。
xmlns:util="http://www.springframework.org/schema/util" <util:list id="trackList"><value>......</value><value>.....</value> </util:list>下表展示了Spring util-命名空间中的元素
| util:constant | 引用某个类型的public static域,并将其暴露为bean |
| util:list | 创建一个java.util.List类型的bean,其中包含值或引用 |
| util:map | 创建一个java.util.Map类型的bean,其中包含值或引用 |
| util:properties | 创建一个java.util.Propertie类型的bean |
| util:property-path | 引用一个bean的属性(或内嵌属性),并将其暴露为bean |
| util:set | 创建一个java.util.Set类型的bean,其中包含值或引用 |
2.5 导入和混合配置
2.5.1 在JavaConfig中引用XML配置
使用@Import注解引用其他JavaConfig配置,使用@ImportResource注解引入XML配置。
@Configuration @Import(CDPlayerConfig.class) @ImportResource("classpath:cd-config.xml") public class SoundSystemConfig {}2.5.2 在XML配置中引用JavaConfig
在XML中可以使用<import>元素来引用其他XML配置。
将JavaConfig作为bean使用<bean>元素导入XML配置文件。
转载于:https://my.oschina.net/u/2453016/blog/1532349
总结
以上是生活随笔为你收集整理的《Spring实战》第四版读书笔记 第二章 装配Bean的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 并查集(Union-Find)算法介绍
- 下一篇: 利用JSON-schema校验请求报文,