Spring具有非常大的靈活性,它提供了三種主要的裝配機制:
- 在XML中進(jìn)行顯式配置。
- 在Java中進(jìn)行顯式配置。
- 隱式的bean發(fā)現(xiàn)機制和自動裝配。
一、自動化裝配bean
Spring從兩個角度來實現(xiàn)自動化裝配:
- 組件掃描(component scanning):Spring會自動發(fā)現(xiàn)應(yīng)用上下文中所創(chuàng)建的bean。
- 自動裝配(autowiring):Spring自動滿足bean之間的依賴。
1.首先創(chuàng)建CompactDisc.java文件,里面頂一個一個接口:
package com.df.test.service.impl;
public interface CompactDisc {
void play();
}
2.然后定義它的實現(xiàn)類:
package com.df.test.service.impl;
import org.springframework.stereotype.Component;
@Component
public class SgtPeppers implements CompactDisc {
public void play() {
// TODO Auto-generated method stub
System.out.println("播放音樂...");
}
}
需要注意的就是SgtPeppers類上使用了@Component注解。這個簡單的注解表明該類會作為組件類,并告知Spring要為這個類創(chuàng)建bean。沒有必要顯式配置SgtPeppersbean,因為這個類使用了@Component注解,所以Spring會為你把事情處理妥當(dāng)。不過,組件掃描默認(rèn)是不啟用的。我們還需要顯式配置一下Spring,從而命令它去尋找?guī)в蠤Component注解的類,并為其創(chuàng)建bean。如下設(shè)置Spring對組件進(jìn)行掃描:
package com.df.test.service.impl;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan
public class CDPlayerConfig {
}
使用了@ComponentScan注解,這個注解能夠在Spring中啟用組件掃描。如果沒有其他配置的話,@ComponentScan默認(rèn)會掃描與配置類相同的包。因為CDPlayerConfig類位于com.df.test.service.impl包中,因此Spring將會掃描這個包以及這個包下的所有子包,查找?guī)в蠤Component注解的類。并且會在Spring中自動為其創(chuàng)建一個bean。
當(dāng)然也可以XML來啟用組件掃描:
<context:component-scan base-package="com.df.test.service.impl" />
測試代碼如下:
package com.df.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.df.test.service.impl.CDPlayerConfig;
import com.df.test.service.impl.CompactDisc;
import com.df.test.service.impl.SgtPeppers;
@RunWith(SpringJUnit4ClassRunner.class) //表示繼承了SpringJUnit4ClassRunner類
@ContextConfiguration(classes= CDPlayerConfig.class)
public class JavaTestMethod {
@Autowired CompactDisc cd;//這里,不論我是用CompactDisc接口還是SgtPeppers實現(xiàn)類,下面都有輸出,都是同一個對象SgtPeppers。
@Test
public void testMethod() {
cd.play();
}
}
@Component基本使用。
Spring應(yīng)用上下文中所有的bean都會給定一個ID。在前面的例子中,盡管我們沒有明確地為SgtPeppersbean設(shè)置ID,但Spring會根據(jù)類名為其指定一個ID。具體來講,這個bean所給定的ID為sgtPeppers,也就是將類名的第一個字母變?yōu)樾?。我們也可以給bean命名,像下面代碼這樣。有時候可以用@Named代替@Component使用:
@Component("myComponentName")
public class SgtPeppers implements CompactDisc {
...
}
@ComponentScan基本使用。
不但可以默認(rèn)設(shè)置,還可以指定多個不同的基礎(chǔ)包作為掃描對象,使用basePackages屬性,String[]類型。
另外一種方法,那就是將其指定為包中所包含的類或接口,使用 basePackageClasses屬性,這些類所在的包將會作為組件掃描的基礎(chǔ)包。,Class<?>[]類型:。
//一下兩種方法,任意一種都可以實現(xiàn)
@Configuration
@ComponentScan(basePackages = {"com.df.test.service.impl","com.df.test.dao"})
public class CDPlayerConfig {
}
@Configuration
@ComponentScan(basePackageClasses = {SgtPeppers.class})
public class CDPlayerConfig {
}
@Autowired 實現(xiàn)自動裝配。
簡單來說,自動裝配就是讓Spring自動滿足bean依賴的一種方法,在滿足依賴的過程中,會在Spring應(yīng)用上下文中尋找匹配某個bean需求的其他bean。假如有且只有一個bean匹配依賴需求的話,那么這個bean將會被裝配進(jìn)來。如果沒有匹配的bean,那么在應(yīng)用上下文創(chuàng)建的時候,Spring會拋出一個異常。因為是按照類型進(jìn)行匹配,所以如果有多個bean都能滿足依賴關(guān)系的話,Spring將會拋出一個異常,表明沒有明確指定要選擇哪個bean進(jìn)行自動裝配。@Autowired注解不僅能夠用在構(gòu)造器上,還能用在屬性的Setter方法上,還可以在屬性上。如下代碼,下面三個屬性對象,都會完成自動裝配,可以用@Inject在大多數(shù)情況下來代替@Autowired 。@Named和@Inject來源于Java依賴注入規(guī)范。
package com.df.test.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class CDPlayer {
@Autowired
private CompactDisc cd;
private CompactDisc cd2;
private CompactDisc cd3;
@Autowired
public CDPlayer(CompactDisc cd2) {
this.cd2 = cd2;
}
@Autowired
public void setCd3(CompactDisc cd3) {
this.cd3 = cd3;
}
public void play(){
cd.play();
cd2.play();
cd3.play();
}
}
二、通過Java代碼裝配bean
通過JavaConfig顯式配置Spring:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CDPlayer02 {
@Bean
public CompactDisc getBeanI(){
return new SgtPeppers();
}
}
@Bean注解基本使用。
創(chuàng)建JavaConfig類的關(guān)鍵在于為其添加@Configuration注解,@Configuration注解表明這個類是一個配置類,該類應(yīng)該包含在Spring應(yīng)用上下文中如何創(chuàng)建bean的細(xì)節(jié)。@Bean注解會告訴Spring這個方法將會返回一個對象,該對象要注冊為Spring應(yīng)用上下文中的bean。方法體中包含了最終產(chǎn)生bean實例的邏輯。所以這里就很靈活了,可以一個方法,返回很多個不同的對象根據(jù)不同的邏輯條件。默認(rèn)情況下,bean的ID與帶有@Bean注解的方法名是一樣的。也可以通過name屬性指定一個不同的名字。
三、通過XML裝配bean
Spring剛出來的時候,就是以這種方式。所以這里就不做過多解釋了??梢酝ㄟ^set方法注入,也可以通過構(gòu)造方法注入。
<?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.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="customerDAO" class="com.sanxin.org.jdbc.JdbcCustomerDAO">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
我是分割線
混合配置
以上已經(jīng)將三種裝配bean的 方式講完了,現(xiàn)在說說混合配置
1.JavaConfig配置之間相互引用
假設(shè)由于有兩個JavaConfig配置的類:
@Configuration
public class CDPlayer02 {
@Bean
public CompactDisc getBean02(){
return new SgtPeppers02();
}
}
@Configuration
public class CDPlayer01 {
@Bean
public CompactDisc getBea01(){
return new SgtPeppers01();
}
}
我們需要有一種方式將這兩個類組合在一起,可以這樣做,使用@Import:
@Configuration
@Import(CDPlayer02 .class)
public class CDPlayer01 {
@Bean
public CompactDisc getBea01(){
return new SgtPeppers01();
}
}
也可以干脆這樣:
@Configuration
@Import({CDPlayer01 .class,CDPlayer2 .class})
public class CDPlayer01 {
}
2.在JavaConfig中引用XML配置
假設(shè)有cd-config.xml配置文件
@Configuration
@Import(CDPlayer02 .class)
@ImportResource("classpath:cd-config.xml")
public class CDPlayer01 {
@Bean
public CompactDisc getBea01(){
return new SgtPeppers01();
}
}
3.在XML配置中引用JavaConfig
<?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.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<!-- 這就是那個JavaConfig配置類 -->
<bean class = "com.df.test.service.impl.CDConfig"/>
<bean id="customerDAO" class="com.sanxin.org.jdbc.JdbcCustomerDAO">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
4.在XML配置中引用XML配置
<?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.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<!-- 這就是那個JavaConfig配置類 -->
<bean class = "com.df.test.service.impl.CDConfig"/>
<!-- 這就是另一個那個xml配置文件 -->
<improt resource = "cdplayer-config.xml" />
</beans>
以上就是bean裝配的三種方式。上一篇Spring容器。