Spring裝配bean的三種方式
1、在xml中進行顯示配置
2、在javaConfig中進行顯示配置
3、隱式的bean發現機制和自動裝配
本次將詳細介紹前兩種裝配方式
通過JAVA代碼裝配bean
步驟:
1、創建JavaConfig配置類
關鍵在於在JavaConfig類上添加@Configuration註解
@Configuration註解表明該類是一個配置類
2、在配置類中聲明簡單的bean,例如:
@Bean
public SimpleMovieLister getSimpleMovieLister(){
return new SimpleMovieLister();
}
@Bean註解將會告訴Spring這個方法將會返回一個對象,該對象要註冊爲Spring應用上下文的bean。方法體中包含了最終產生bean實例的邏輯
默認情況下,bean的ID與帶有@bean註解的方法名是一樣的。如果想設置不同的名字的話,可以重命名該方法,也可以指定一個不同的名字,如下方式:
@Bean(name="simpleMovieLister")
public SimpleMovieLister getSimpleMovieLister(){
return new SimpleMovieLister();
}
我們可以在getSimpleMovieLister方法中調用SimpleMovieLister類中的有參構造函數或者set方法,從而爲SimpleMovieLister類注入其他bean
通過xml裝配bean
步驟:
1、創建一個xml文件,以<beans></beans>
元素爲根
最簡單的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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
在SpringXML配置中,只有一種聲明bean的方式:使用<bean>
元素指定class屬性。
但是在xml中聲明DI(依賴注入)時,會有多種可選的方案和風格。
例如:
1、構造器注入:
a、構造器通過名稱注入bean或基本類型屬性,代碼如下:
<bean id="exampleBean" class="com.cn.test.ExampleBean">
<constructor-arg name="years" value="7500000"/>
<constructor-arg name="ultimateAnswer" value="421"/>
<constructor-arg name="bean" ref="beannnn"></constructor-arg>
</bean>
b、構造器通過位置注入bean或基本類型屬性,代碼如下:
<bean id="exampleBean" class="com.cn.test.ExampleBean">
<!--位置方式:使用index-->
<constructor-arg index="0" value="7500005"></constructor-arg>
<constructor-arg index="1" value="436"></constructor-arg>
<!--若是複雜屬性,則使用ref-->
<constructor-arg index="2" ref="beannnn"></constructor-arg>
</bean>
以上兩個構造器注入實例,當基本參數時,使用value=”xxx”,當引用類型時使用ref=”bean的id值”
c、構造器通過命名空間c-注入bean或基本類型屬性
若使用命名空間c-,則首先需要在xml的頂部聲明起模式,如下所示:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:c="http://www.springframework.org/schema/c"
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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
...
</beans>
使用方式如下:
<bean id="exampleBeanC" class="com.cn.test.ExampleBean" c:years="7500000" c:ultimateAnswer="422" c:bean-ref="beannnn"/>
說明:屬性名以c:開頭,也就是命名空間的前綴;接下來就是要裝配的構造器的參數名,在此之後是”-ref”,這是一個命名的約定,它會告訴spring正在裝配的是一個bean引用。要注入的bean的id是beannnn
c:name=”構造函數依賴Name值” c:name-ref=”構造函數依賴bean”
d、構造器命名空間方式按位置注入
<bean id="exampleBeanC" class="com.cn.test.ExampleBean" c:_0="7500000" c:_1="422" c:_2-ref="beannnn"/>
將參數的名稱換爲0,1,2即使用了參數的索引。若構造器只有一個參數,則可省去索引值
2、構造器注入集合類型
a、list容器內是String類型數據
<bean id="exampleBean" class="com.cn.test.ExampleBean">
<constructor-arg name="list">
<list>
<value>value1</value>
<value>value2</value>
</list>
</constructor-arg>
</bean>
b、list容器內是bean類型數據
<bean id="exampleBean" class="com.cn.test.ExampleBean">
<constructor-arg name="list">
<list>
<ref bean="beannnn"/>
</list>
</constructor-arg>
</bean>
同理可配置set,properties,map等集合
若創建set集合所有重複值都會被忽略掉,存放順序也不會得以保證。目前使用c-方式無法實現裝配集合屬性的功能
3、基於屬性的setter方法注入
a、名稱注入:
<bean id="exampleBeanP" class="com.cn.test.ExampleBean">
<property name="years" value="7500001"></property>
<property name="ultimateAnswer" value="433"></property>
<!--若是複雜屬性,則使用ref-->
<property name="bean" ref="beannnn"></property>
</bean>
<property>
元素爲屬性的Setter方法所提供的功能與<constructor-arg>
元素爲構造器所提供的功能是一樣的
ref的值表示將id值爲beannnn的bean注入名稱爲setBean方法的
b、命名空間注入:
若使用命名空間注入,首先需要在xml頂部添加聲明,如下:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
...
</beans>
<bean id="exampleBeanC" class="com.cn.test.ExampleBean" p:years="7500000" p:ultimateAnswer="422" p:bean-ref="beannnn"/>
說明:屬性名以p:開頭,也就是命名空間的前綴;接下來就是要裝配的屬性名成,在此之後是”-ref”,這是一個命名的約定,它會告訴spring正在裝配的是一個bean引用。要注入的bean的id是beannnn
如果沒有-ref後綴的話,所裝配的就是字面量,即基本屬性
4、基於屬性的setter方法注入集合
<bean id="complexObject" class="com.cn.test.ComplexObject">
<property name="adminEmails">
<props>
<prop key="administrator">[email protected]</prop>
<prop key="support">[email protected]</prop>
<prop key="development">[email protected]</prop>
</props>
</property>
<!-- results in a setSomeList(java.util.List) call -->
<property name="someList">
<list>
<value>testList1</value>
<value>testList2</value>
</list>
</property>
<!-- results in a setSomeMap(java.util.Map) call -->
<property name="someMap">
<map>
<entry key="map1" value="test111"/>
</map>
</property>
<!-- results in a setSomeSet(java.util.Set) call -->
<property name="someSet">
<set>
<value>set1</value>
<value>set2</value>
</set>
</property>
</bean>
5、使用Spring util-命名空間簡化bean配置
首先需要在xml頂部聲明util-命名空間及模式
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
使用案例:
<bean id="complexObject" class="com.cn.test.ComplexObject">
<property name="someList" ref="someList"></property>
</bean>
<util:list id="someList">
<value>[email protected]</value>
<value>[email protected]</value>
<value>[email protected]</value>
</util:list>
Spring util-命名空間的元素
<util:constant/>
引用某個類型的public static域,並將其暴露爲bean
<util:list></util:list>
創建一個java.util.List類型的bean,其中包含值或引用
<util:map></util:map>
創建一個java.util.Map類型的bean,其中包含值或引用
<util:properties></util:properties>
創建一個java.util.Properties類型的bean,其中包含值或引用
<util:property-path/>
引用一個bean的屬性(或內嵌屬性),並將其暴露爲bean
<util:set></util:set>
創建一個java.util.Set類型的bean,其中包含值或引用
導入和混合配置
1、JavaConfig使用@Import註解導入一些其他JavaConfig配置,從而進行配置拆分,是配置看起來更加整潔
@Import({AppConfig1.class,AppConfig2.class})
2、JavaConfig使用@ImportResource註解導入一些其他xml配置
@ImportResource({“classpath:xxx1.xml”,”classpath:xxx2.xml”})
3、使用<import>
元素引入其他xml文件,利於xml文件拆分
<import resource="要引入的xml路徑"/>
4、xml文件中引入JavaConfig配置文件
<bean class="JavaConfig全限定名"></bean>
其他雜記
@Component 應用在一個類上,表示該類是一個組件類,並告知spring要爲該類創建bean
@ComponentScan 啓用組件掃面,默認規則會以配置類所在的包作爲基礎包basePackages來掃描組件
@ComponentScan(basePackages = “xxx.xx.xxx”)若是想掃描不同的包配置basePackages=”想掃描的包名”,若是想掃描多個包
可以配置@ComponentScan(basePackages = { “xxx.xx.xxx.包1”,”xxx.xx.xxx.包2”})
@ComponentScan(basePackageClasses=BeanConfig.class)除了將包設置爲簡單的String類型表示之外,@ComponentScan還
提供了另一種方法,那就是將其指定爲包中所包含的類或接口。
@ComponentScan 作用等同於xml中配置的<context:component-scan base-package="xxx.xx.xxx"/>
@RunWith(SpringJUnit4ClassRunner.class) 使用spring-test做單元測試
@ContextConfiguration(classes=AppConfig.class)加載配置類AppConfig
@ContextConfiguration(locations = {“classpath:META-INF/spring/applicationContext-redis.xml”)加載xml配置文件