最小化Spring XML配置


Spring提供兩種技巧,可以幫助我們減少XML的配置數量。

1.自動裝配(autowiring)有助於減少甚至消除配置<property>元素和<constructor-arg>元素,讓Spring自動識別如何裝配Bean的依賴關系。

2.自動檢測(autodiscovery)比自動裝配更進一步,讓Spring自動識別哪些類需要被配置成Spring Bean,從而減少對<bean>元素的使用。

 

一、4種類型的自動裝配

1.byName,把與Bean的屬性具有相同名字(或者ID)的其他Bean自動裝配到Bean的對應屬性中。如果沒有跟屬性的名字相匹配的Bean,則該屬性不進行裝配。

<bean id="instrument" class="cn.edu.stu.springidol.Saxphone" />
    
<bean id="kenny2" class="cn.edu.stu.springidol.Instrumentalist" autowire="byName">
    <property name="song" value="Jingle Bells" />
</bean>

Saxphone的id屬性與kenny的instrument屬性的名字是一樣的。

缺點:需要假設Bean的名字與其他Bean的屬性名字一樣。

 

2.byType,把與Bean的屬性具有相同類型的其他Bean自動裝配到Bean的對應屬性中,如果沒有跟屬性的類型相匹配的Bean,則該屬性不被裝配。

<bean id="saxphone" class="cn.edu.stu.springidol.Saxphone" />

<bean id="kenny2" class="cn.edu.stu.springidol.Instrumentalist" autowire="byType">
    <property name="song" value="Jingle Bells" />
</bean>

 缺點:如果Spring尋找到多個Bean的類型與需要自動裝配的類型都相匹配,Spring不會猜測哪一個Bean更適合裝配,而是拋出一個異常,所以應用只允許存在一個Bean與需要自動裝配的屬性類型相匹配。

兩種解決方法可以解決byType帶來的歧義:

1.聲明候選Bean的primary屬性為true,但默認的primary屬性是true的,所以必須聲明除候選Bean外的其他非候選Bean的primary屬性為false

2.設置在自動裝配時被忽略的Bean,autowire-candidate屬性為false,要求Spring在自動裝配時,忽略Bean作為候選Bean

 

3.constructor,把與Bean的構造器入參具有相同類型的其他Bean自動裝配到Bean構造器的對應入參中。

如果通過構造器注入來配置Bean,可以移除<constructor-arg>元素

<bean id="duke2" class="cn.edu.stu.springidol.PoeticJuggler" autowire="constructor" />

缺點:當發現多個Bean匹配構造器入參,Spring不會猜測哪一個更適合,此外,如果一個類有多個構造器都滿足自動裝配條件,Spring也不會猜測哪一個更適合。

 

4.autodetect,首先嘗試使用constructor進行自動裝配,如果失敗,再嘗試使用byType進行自動裝配。

2.5之前還可以使用,3.0之后就沒有了。

 

默認自動裝配:

在<beans>上增加一個default-autowire屬性,作用於Spring配置文件的所有Bean,可以用<bean>元素的autowire屬性覆蓋<beans>的默認自動裝配策略。

 

還可以使用混合使用自動裝配和顯示裝配。

 

二、使用注解裝配

Spring容器默認禁用注解裝配,啟用方式的使用context命名空間配置中的<context:annotation-config>元素。

<?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.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <context:annotation-config />

</beans>

 

1.使用@Autowired

不僅可以標注setter方法,還可標注需要自動裝配Bean引用的任意方法,構造器,屬性。

可選的自動裝配,屬性不一定非要裝配,null值也可以接受,通過設置required屬性為false來配置自動裝配是可選的。但是當使用構造器裝配時,只有一個構造器可以將required屬性設置為true,其他使用@Autowired注解標注的構造器只能將required設置為false,當使用@Autowired標注多個構造器,Spring選擇滿足裝配條件中入參最多的那個。

限定歧義性的依賴,可能有至少兩個Bean完全滿足裝配條件,如何選擇。

使用Qualifier("beanID")明確指定注入ID為beanID的Bean

或者:

XML聲明Bean

<bean id="saxphone" class="cn.edu.stu.springidol.Saxphone">
    <qualifier value="stringed" />
</bean>
@Autowired
@Qualifier("stringed")
private Instrument instrument;

還可以創建自定義的限定器。

 

2.@Inject實現基於標准的自動裝配

可以用來自動裝配屬性、方法和構造器,與@Autowired不同的是,沒有required屬性。

限定@Inject所標注的屬性,使用@Named("beanID")

 

創建自定義限定器,與@Autowired類似。

 

在注解中使用表達式:

@Value("Eruption")
private String song;

@Value("#{systemProperties.myFavoriteSong}")
private String song;

 

三、自動檢測Bean

<context:annotation-config>有助於消除<property>和<constructor-arg>元素,但仍需要使用<bean>顯示定義Bean。

<context:component-scan>除了完成<context:annotation-config>一樣的工作,還允許spring自動檢測Bean和定義Bean,這意味着不使用<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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <context:component-scan 
        base-package="cn.edu.stu.springidol">
    </context:component-scan>

</beans>

<context:component-scan>會掃描指定的包及其所有子包,並找出能夠自動注冊為Spring的類。

如何知道哪些類需要注冊為Spring Bean?

 

1.為自動檢測標注Bean

<context:component-scan>會查找使用構造型注解所標注的類

i.@Component,通用的構造性注解,標識該類為Spring組件

ii.@Controller,標識該類定義為Spring MVC controller

iii.@Repository,標識該類定義為數據倉庫

iv.@Service,標識該類定義為服務

v.使用@Component標注的任意自定義注解

 

import org.springframework.stereotype.Component;

@Component
public class Guitar implements Instrument {

    @Override
    public void play() {
        System.out.println("Strum Strum Strum");

    }

}

Guitar會被自動地注冊為Spring Bean,ID默認為無限定類名,這里是guitar,可以通過@Component("anotherName")顯式命名ID。

 

2.過濾組件掃描

使用<context:include-filter>告知哪些類需要注冊為Spring Bean,使用<context:exclude-filter>告知哪些類不需要注冊為Spring Bean。

 

5種過濾器類型:

i.annotaion,使用指定注解所標注的類,通過expression屬性指定要掃描的注解

ii.assignable,掃描派生於expression屬性指定類型的那些類

iii.aspject,掃描expression屬性所指定的AspectJ表達式所匹配的那些類

iv.custom,使用自定義的org.springframework.core.type.TypeFilter實現類,該類由expression指定

v.regex,掃描類的名稱與expression屬性所指定的正則表達式所匹配的那些類

 

四、使用Spring基於Java的配置(為了不使用XML為目的)

1.創建基於Java的配置

首先啟動<context:component-scan>,這需要少量的XML配置,

<context:component-scan>會自動注冊那些使用某種構造型注解所標注的Bean,但它也會自動加載使用@Configuration注解所標注的類。

 

2.定義一個配置類(類放在base-package指定的包下)

@Configuration
public class SpringIdolConfig {
    
}

 

3.聲明一個簡單Bean

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SpringIdolConfig {
    @Bean
    public Performer duke() {
        return new Juggler();
    }
}

使用@Bean注解標注的duke方法會告知Spring我們希望該方法定義的Bean被注冊進Spring的應用上下文中,因此,在其他Bean的聲明方法中引用這個方法,Spring會攔截該方法的調用,並嘗試在應用上下文中查找該Bean,而不是讓方法創建一個新的實例。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM