bean
是Spring
最基礎最核心的部分,Spring
簡化代碼主要是依賴於bean
,下面學習Spring
中如何裝配bean
。java
Spring
在裝配bean
時很是靈活,其提供了三種方式裝配bean
。node
XML
中進行顯式配置。Java
中進行顯式配置。bean
發現機制和自動裝配。自動化裝配技術最爲便利,
Spring
從兩個角度實現自動化裝配。spring
Spring
會自動發現應用上下文中所建立的bean
。Spring
自動知足bean
之間的依賴。<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.hust.grid.leesf.spring</groupId> <artifactId>spring-learning</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.version>3.1.2.RELEASE</spring.version> <cglib.version>3.1</cglib.version> <junit.version>4.11</junit.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib-nodep</artifactId> <version>${cglib.version}</version> </dependency> </dependencies> </project>
package ch2; interface CompactDisc { void play(); }
其只定義了一個
play
接口,由子類實現。apache
package ch2; import org.springframework.stereotype.Component; @Component public class SgtPeppers implements CompactDisc { private String title = "Sgt. Pepper's Lonely Hearts Club Band"; private String artist = "The Beatles"; public void play() { System.out.println("Playing " + title + " by " + artist); } }
SgtPeppers
繼承了CompactDisc
接口,使用Component
註釋爲一個Bean
。maven
package ch2; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan("ch2") public class CDPlayerConfig { }
配置類,
Spring
會自動加載上下文並掃描ch2
包下的全部bean
。ide
package ch2; 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 static org.junit.Assert.assertNotNull; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = CDPlayerConfig.class) public class CDPlayerTest { @Autowired private CompactDisc cd; @Test public void cdShouldNotNull() { assertNotNull(cd); } }
該類用於測試是否成功裝配
CompactDisc
的bean
,測試成功。函數
上述示例中
bean
的名稱默認爲sgtPeppers
,即將類名的首字母小寫,固然可經過@Component("sp")
設置其名稱爲sp
;或者使用@Named("sp")
進行設置。學習
上述示例中指定掃描
ch2
包,這是經過@ComponentScan("ch")
指定的,固然能夠經過@ComponentScan(basePackages="ch2")
進行設置。若設置多個包,則可採用@ComponentScan(basePackages={"ch2","video"})
方式進行設置。除了使用字符串格式代表包名,也可以使用類名格式,如@ComponentScan(basePackageClasses = SgtPeppers.class)
指定掃描類。測試
示例中使用
@Autowired
實現自動裝配,Spring
應用上下文中尋找某個匹配的bean
,因爲示例中CompactDisc
只有一個聲明爲bean
的子類,如有多個聲明爲bean
的子類,則會報錯,若沒有子類,也會報錯。@Autowired
註解不只能夠用在屬性上,也能夠用在構造函數上,還能夠用在Setter方法上。若使用@Autowired(required=false)
時,那麼沒有符合的bean
時不會報錯,而是處於未裝配的狀態,要防止空指針狀況,其與@Inject
註解功能相似。ui
@Autowired
註解@Component public class CDPlayer implements MediaPlayer { private CompactDisc cd; @Autowired public CDPlayer(CompactDisc cd) { this.cd = cd; } public void play() { } }
Setter
方法使用@Autowired
註解@Autowired public void setCompactDisc(CompactDisc cd) { this.cd = cd; }
在配置類中顯式配置
bean
,將CDPlayerConfig
中的@ComponentScan("ch2")
移除,此時運行測試用例會報錯,下面經過顯式配置方法來配置bean
。修改CDPlayerConfig
代碼以下。
package ch2; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class CDPlayerConfig { @Bean public CompactDisc sgtPeppers() { return new SgtPeppers(); } }
上述生成的
bean
名稱與方法名相同,若想設置名稱,可經過@Bean(name=sp)
進行設置。對於以下代碼,調用sgtPeppers
會生成同一個sgtPeppers
的bean
,這是因爲sgtPeppers
方法標記爲Bean
,Spring
會攔截全部對該方法的調用,而且返回一個已經建立的bean
實例。默認狀況下,Spring
中的bean
都是單例的。
@Bean public CDPlayer cdPlayer() { return new CDPlayer(sgtPeppers()); } @Bean public CDPlayer anotherCDPlayer() { return new CDPlayer(sgtPeppers()); }
還可使用以下方法來引用bean
@Bean public CDPlayer cdPlayer(CompactDisc compactDisc) { return new CDPlayer(compactDisc); }
這樣會自動裝配一個CompactDisc
到配置方法中,不用明確使用sgtPeppers
方法來構造CDPlayer
。
除了使用
JavaConfig
來顯式裝配bean
外,還可使用xml
文件來裝配bean
。若想在xml
中聲明一個bean
元素,則須要以下操做。
<?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" xmlns:c="http://www.springframework.org/schema/c" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.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"> <bean id="sgtPeppers" class="ch2.SgtPeppers" /> </beans>
上述xml
文件中聲明瞭一個名爲sgtPeppers
的bean
,會調用SgtPeppers
的默認構造函數建立bean
。
<bean id="cdPlayer" class="ch2.CDPlayer"> <constructor-arg ref="compactDisc"/> </bean>
上述代碼表示將ID
爲compactDisc
的bean
引用傳遞到CDPlayer
的構造器中。
<bean id="cdPlayer" class="ch2.CDPlayer" c:cd-ref="compactDisc"/> </bean>
其中c:
表示命名空間前綴;cd
表示構造器參數名;-ref
表示注入的bean
的引用;compactDisc
表示要注入的bean
的ID
。
<bean id="compactDisc" class="ch2.BlankDisc"> <constructor-arg value="Sgt. Pepper's Lonely Hearts Club Band" /> <constructor-arg value="The Beatles" />
或者使用
<bean id="compactDisc" class="ch2.BlankDisc" <c:_title="Sgt. Pepper's Lonely Hearts Club Band" /> <c:artist="The Beatles" />
<bean id="compactDisc" class="ch2.BlankDisc"> <constructor-arg value="Sgt. Pepper's Lonely Hearts Club Band" /> <constructor-arg value="The Beatles" /> <constructor-arg> <list> <value>Sgt.AA</value> <value>Sgt.BB</value> <value>Sgt.CC</value> </list> </constructor-arg> </bean>
<bean id="compactDisc" class="ch2.BlankDisc"> <constructor-arg value="Sgt. Pepper's Lonely Hearts Club Band" /> <constructor-arg value="The Beatles" /> <constructor-arg> <list> <ref bean="sgtPeppers"/> <ref bean="whiteAlbum"/> <ref bean="revolver"/> </list> </constructor-arg> </bean>
同理,對於Set
集合只需修改list
爲set
便可。
<bean id="cdPlayer" class="ch2.CDPlayer"> <property name="compactDisc" ref="compactDisc"> </bean>
<bean id="cdPlayer" class="ch2.CDPlayer" p:compactDisc-ref="compactDisc"> </bean>
其組成與c-
相似。
<bean id="compactDisc" class="ch2.BlankDisc"> <property name="title" value="Sgt. Pepper's Lonely Hearts Club Band" /> <property name="artist"value="The Beatles" /> <property name="tracks"> <list> <value>Sgt.AA</value> <value>Sgt.BB</value> <value>Sgt.CC</value> </list> </property> </bean>
<bean id="compactDisc" class="ch2.BlankDisc"> <p:title="Sgt. Pepper's Lonely Hearts Club Band" /> <p:artist="value="The Beatles" /> <property name="tracks"> <list> <value>Sgt.AA</value> <value>Sgt.BB</value> <value>Sgt.CC</value> </list> </property> </bean>
<util:list id="tractList"> <value>Sgt.AA</value> <value>Sgt.BB</value> <value>Sgt.CC</value> </util:list>
此時對應修改以下
<bean id="compactDisc" class="ch2.BlankDisc"> <p:title="Sgt. Pepper's Lonely Hearts Club Band" /> <p:artist="value="The Beatles" /> <p:tracks-ref="trackList" /> </bean>
將
BlankDisc
從CDPlayerConfig
中剝離出來,放置在本身的配置文件CDConfig
中。此時須要在CDPlayerConfig
中使用@Import(CDConfig.class)
將二者組合;或者使用更高級別的Config
中使用@Import({CDPlayerConfig.class,CDConfig.class})
組合二者。若將BlankDisc
配置在cd-config.xml
文件中,則可以使用@ImportResource("classpath:cd-config.xml")
導入。
可使用
import
元素引用配置,如
<import resource="cd-config.xml" />
Spring
有三種方式裝配bean
,使用自動化裝配技術使得代碼更簡潔;而且有多種方式注入屬性。