在Spring中,对象无需本身查找或建立与其所关联的其余对象。相反,容器负责把须要相互协做的对象引用赋予各个对象。java
建立应用对象之间协做关系的行为一般称为装配(wiring),这也是依赖注入的本质。spring
Spring提供了三种主要的装配机制:数组
做者建议尽量的使用自动装配的机制。显式配置越少越好,当必需要显式配置bean的时候(好比,有些源码不是由你来维护的,而当你须要为这些代码配置bean的时候),推荐使用类型安全而且比XML更增强大的JavaConfig。最后,只有当你想要使用便利的XML命名空间,而且在JavaConfig中没有一样的实现是才应该使用XML。安全
Spring从两个角度实现自动化装配:ide
在类上使用@Component注解,这个注解代表该类会做为组件类,并告知Spring要为这个类建立bean。测试
组件扫描默认是不启用的,还须要显式配置一下Spring,从而命令它去寻找带有@Component注解的类并为其建立bean。ui
@Configuation @ComponentScan public class CDPlayerConfig { }
若是没有其余配置,@ComponentScan默认会扫描与配置类相同的包。spa
若是想使用XML来启用组件扫描,可使用Spring context命名空间的context:component-scan元素。code
<?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="soundsystem"/> </beans>
测试组件扫描代码:component
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes=CDPlayerConfig.class) public class CDPlayerText { @Autowired private CompactDisc cd; @Test public void cdShouldNotBeNull() { assertNotNull(cd) } }
CDPlayerTest使用了Spring的SpringJUnit4ClassRunner,以便在测试开始的时候自动建立Spring的应用上下文。注解@ContextConfiguration会告诉它须要在CDPlayerConfig中加载配置。
在组件扫描中若是没有明确的设置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。
若是没有为@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 { }
能够在构造器、setter方法、任何方法上使用@Autowired注解,Spring会尝试知足方法参数上所声明的依赖。假若有且只有一个bean匹配依赖需求,那么这个bean将会被装配进来。
若是没有匹配的bean,那么在应用上下文建立的时候会抛出异常。能够将@Autowired的required属性设置为false,此时Spring会尝试自动装配,可是若是没有匹配的bean的话该属性将会为null。
若是有多个bean都知足依赖关系,Spring将会抛出异常。
@Autowired是Spring特有的注解。可使用@Inject注解替代。
显式的装配方式有两种:Java和XML。
@Configuration注解代表这个类是一个配置类,该类应该包含在Spring应用上下文中如何建立bean的细节。
要在JavaConfig中声明bean,须要编写一个方法,这个方法会建立所需类型的实例,而后给这个方法添加@Bean注解。
@Bean注解会告诉Spring这个方法将返回一个对象,该对象要注册为Spring应用上下文中的bean。方法体中包含了最终产生bean实例的逻辑。
默认状况下,bean的ID与方法名一致。若是想为其设置一个不一样的名字,能够重命名该方法,也能够经过@Bean的name属性指定。
在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之中。
在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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context"> <!-- 配置详情 --> </beans>
<bean>元素相似于JavaConfig中的@Bean注解。
若是没有给定ID,因此这个bean将会根据全限定类名来进行命名。例如“soundsystem.SgtPeppers#0“,其中“#0”是一个计数形式,用来区分相同类型的其余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甚至是数组。
<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,其中包含值或引用 |
使用@Import注解引用其余JavaConfig配置,使用@ImportResource注解引入XML配置。
@Configuration @Import(CDPlayerConfig.class) @ImportResource("classpath:cd-config.xml") public class SoundSystemConfig { }
在XML中可使用<import>元素来引用其余XML配置。
将JavaConfig做为bean使用<bean>元素导入XML配置文件。