Spring Bean的裝配

Spring bean 的裝配方式總的來說有以下3種:基于xml配置文件的裝配、基于注解的裝配、基于命名空間的裝配。三種裝配方式各有優(yōu)缺點,在實際的開發(fā)工作中,根據(jù)“約定優(yōu)于配置”的信條,基于注解的裝配方式比較受歡迎。下面介紹各種 裝配方式

1、基于配置文件的裝配方式

直接上配置文件:

<?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">

<!-- 基本數(shù)據(jù)類型集合依賴bean裝配 -->

<bean id="simpleCollectionBean" class="spring.chapter10.loadbeanbyxml.SimpleCollectionBean">

<property name="list">

<list>

<value>list-value-1</value>

<value>list-value-2</value>

<value>list-value-3</value>

<value>list-value-4</value>

</list>

</property>

<property name="set">

<set>

<value>set-value-1</value>

<value>set-value-2</value>

<value>set-value-3</value>

<value>set-value-4</value>

</set>

</property>

<property name="map">

<map>

<entry key="map-key-1" value="map-value-1" />

<entry key="map-key-2" value="map-value-2" />

<entry key="map-key-3" value="map-value-3" />

<entry key="map-key-4" value="map-value-4" />

</map>

</property>

<property name="properties">

<props>

<prop key="properties-key-1">properties-value-1</prop>

<prop key="properties-key-2">properties-value-2</prop>

<prop key="properties-key-3">properties-value-3</prop>

<prop key="properties-key-4">properties-value-4</prop>

</props>

</property>

<property name="array">

<array>

<value>array-value-1</value>

<value>array-value-2</value>

<value>array-value-3</value>

<value>array-value-4</value>

</array>

</property>

</bean>

<!-- 復(fù)雜對象集合依賴Bean的裝配 -->

<bean id="source1" class="spring.chapter9.ioc.Source">

<property name="fruit" value="橙子" />

<property name="sugar" value="少糖" />

<property name="size"? value="小杯" />

</bean>

<bean id="source2" class="spring.chapter9.ioc.Source">

<property name="fruit" value="蘋果"/>

<property name="sugar" value="適量" />

<property name="size"? value="中杯" />

</bean>

<bean id="source3" class="spring.chapter9.ioc.Source">

<property name="fruit" value="橘子"/>

<property name="sugar" value="多糖" />

<property name="size"? value="大杯" />

</bean>

<bean id="juiceMaker" class="spring.chapter9.ioc.JuiceMaker">

<property name="shopName" value="貢茶" />

<property name="source"? ref="source1" />

</bean>

<bean id="objectCollectionBean" class="spring.chapter10.loadbeanbyxml.ObjectCollectionBean">

<property name="list">

<list>

<ref bean="source1"/>

<ref bean="source2" />

<ref bean="source3" />

</list>

</property>

<property name="map">

<map>

<entry key-ref="source1" value-ref="juiceMaker"/>

<entry key-ref="source2" value-ref="juiceMaker" />

<entry key-ref="source3" value-ref="juiceMaker" />

</map>

</property>

<property name="array">

<array>

<ref bean="source1" />

<ref bean="source2" />

<ref bean="source3" />

</array>

</property>

<property name="set">

<set>

<ref bean="source1" />

<ref bean="source2" />

<ref bean="source3" />

</set>

</property>

</bean>

</beans>

基于配置文件的裝配方式如上,沒什么需要細(xì)講的東西,最后通過

ApplicationContext ctx =?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?new ClassPathXmlApplicationContext("classpath:spring-cfg.xml");

獲取到ApplicationContext接口的實現(xiàn)類對象。

2、基于注解的裝配方式

基于注解的裝配方式需要一個注解配置類(和要裝配的bean在同一個包路徑下或者子包下)

這里我們新建一個配置類AnotationConfig,代碼如下:

@ComponentScan(basePackages= {"spring.chapter10.loadbeanbyanotation"}, basePackageClasses= {Role.class})

public class AnotationConfig {

}

可以看到這個類其實并沒有任何實際代碼,起作用的是上面加粗的注解部分

basePackages指明要裝載的bean的包路徑或者父包路徑,可以指定多個路徑(要注意bean id是否重復(fù))

basePackageClasses指定要裝載的Bean(不指定默認(rèn)裝載所有的Bean)

要裝載的Bean需要用@component注解

//也可簡寫為@Component("role")

@Component(value = "role")

public class Role {

@Value("administrator")

private String name;

@Value("default")

private String note;

//Spring會把字符串類型轉(zhuǎn)換為Long型

@Value("1")

private Long id;

/**getter and setter*/

}

獲取ApplicationContext接口實現(xiàn)對象:

ApplicationContext? ctx =

new AnnotationConfigApplicationContext(AnotationConfig.class);

上述的Bean的依賴都是基本數(shù)據(jù)類型比如 @Value("1") private Long id;那如果依賴的是自定義的類怎么辦呢?

這時候就需要@Autowired自動裝配注解

@Autowired自動裝配注解又分為根據(jù)類型自動裝配、根據(jù)依賴的bean id自動裝配、根據(jù)優(yōu)先級自動裝配。

默認(rèn)的裝配方式是根據(jù)類型自動裝配,代碼如下:

public class RoleService{

@Autowired

private Role? role = null;

/**getter and setter*/

}

但是這里存在一個問題,如果Role是一個接口,而它的實現(xiàn)類不止一個呢,那么spring初始化的時候會拋出異常

這時候可以通過@Primary注解來指定優(yōu)先的Bean依賴注入

@Component("roleImpl1")

@Primary

public class RoleImpl1 implements Role{

}

@Component("roleImpl2")

public class RoleImpl2 implements Role{

}

那么這時候,Spring會優(yōu)先將bean roleImpl1注入到RoleService中

除此之外還可以使用@Qualifier注解來根據(jù)bean id自動裝配

public class RoleService{

@Autowired

@Qualifier("roleImpl2")

private Role role = null;

}

這時候就會使用roleImpl2注入到RoleService中

三種自動裝配方式的優(yōu)先級: 根據(jù)bean id 也就是@Qualifier > @Primary > byType也就是默認(rèn)的根據(jù)類型裝配

@Autowired還可以用于構(gòu)造方法參數(shù)自動裝配

public class RoleService{

private Role role = null;

public RoleService(@Autowired Role role){

this.role = role;

}

3、裝配的混合使用

各種裝配方式各有優(yōu)缺點,在實際的開發(fā)工作中,工程內(nèi)的bean通常采用注解進(jìn)行配置。

第三方的jar包里的bean通常采用xml文件進(jìn)行配置,這樣可以不考慮第三方項目的實現(xiàn)細(xì)節(jié)。

<!-- 下面的配置演示第三方的jar采用xml配置Bean,工程系統(tǒng)內(nèi)Bean采用注解的方式,即混合使用 -->

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">

<property name="driverClassName" value="com.mysql.jdbc.Driver" />

<property name="url" value="jdbc:mysql://localhost:3306/chapter10" />

<property name="username" value="root" />

<property name="password" value="123456" />

</bean>

創(chuàng)建RoleDaoImpl代碼如下:

@Component("roleDaoImpl")

public class RoleDaoImpl implements RoleDao{

@Autowired

private DataSource dataSource = null;

public Role getRoleById(Long id) {

Connection connection = null;

PreparedStatement ps = null;

ResultSet rs = null;

String sql = "SELECT * FROM t_role WHERE id = ?";

try {

connection = dataSource.getConnection();

ps = connection.prepareStatement(sql);

ps.setLong(1, id);

rs = ps.executeQuery();

while(rs.next()) {

Role role = new Role();

role.setId(id);

role.setName(rs.getString("name"));

role.setNote(rs.getString("note"));

return role;

}

} catch (SQLException e) {

e.printStackTrace();

}finally {

if(connection != null) {

try {

connection.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

return null;

}

}

注解信息配置類AnotationConfig:

@ImportResource("classpath:spring-cfg-chapter10.xml") //可以在注解配置類中引入xml配置,可以通過多個@importResource注解導(dǎo)入多個配置文件

但是spring目前還不支持在xml配置中引入注解類但是可以通過掃包的方式

/**

*

* @author John

* 通過這個配置類,Spring會掃描同包或者子包下的所有注解Component的Bean

*可以指定掃描的包路徑和需要掃描的類

*/

@ComponentScan(basePackages= {"spring.chapter10.loadbeanbyanotation"}, basePackageClasses= {Role.class})

public class AnotationConfig {

}

另外也可以根據(jù)業(yè)務(wù)模塊產(chǎn)生多個xml配置文件,然后在一個總的配置文件中import它們,如下:

<import resource="spring-datasource.xml" />

<import resource="spring-logg.xml />

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容