自動裝配(autowiring):有助于減少<PRoperty>和<constructor-arg>,讓spring自動識別如何裝配Bean的依賴關系。
自動檢測(autodiscovery):讓spring自動識別那個類要被裝配成spring Bean,減少對<bean>元素的使用。
1.自動裝配Bean屬性
1.1 4中類型的自動裝配
1.byName:把與Bean的屬性具有相同名字(或者ID)的其他Bean自動裝配到Bean的對應屬性中。如果沒有與屬性的名字相匹配的Bean,則該屬性不進行裝配。
2.byType:把與Bean的屬性具有相同類型的其他Bean自動裝配到Bean的對應屬性中。如果沒有與屬性的類型相匹配的Bean,則該屬性不進行裝配。
3.constructor:把與Bean的構造器入參具有相同類型的其他Bean自動裝配到Bean構造器的對應入參中。
4.autodetect:先按constructor來裝配,失敗了按byType來裝配。
1.1.1 byName自動裝配
<bean id="aaa" clas=""/><bean id="bbb" class="" > <property name="aaa" ref="aaa"/></bean>如果bbb中aaa屬性名字和Bean的id相同,則可以自動裝配。如果bean的id和property的name相同,那么可以變?yōu)橄旅娴倪@種方式:
<bean id="aaa" clas=""/><bean id="bbb" class="" autowire="byName"> </bean>如果一個Bean中屬性和其他Bean的id相同就會自動裝配,可是自己不需要自動裝配。byName的缺點就是要假設屬性名和Bean的id要一樣。
1.1.2 byType自動裝配
跟byName一樣,只是ByType不去找屬性名一樣,而是去找屬性的類型。
<bean id="aaa" clas="A"/><bean id="bbb" class="" > <property name="aaa" ref="aaa"/></bean>如果bbb中屬性aaa為A類型,則可以byType自動裝配,把autowire="byType"<bean id="aaa" clas="A"/><bean id="bbb" class="" autowire="ByType"> </bean> 如果byType找到多個Bean,那么拋出異常,應用只允許存在一個Bean與需要的自動裝配的屬性相匹配。byName不會找到多個,因為Bean的id是不一樣的。解決的辦法就是可以標識一個首選Bean,也可以讓其他Bean失去資格。<bean>元素有個primary屬性表示首選Bean,但是默認為true,所有的Bean都是首選Bean,所以要把非首選的Bean設置為false。<bean>的autowire-candidate屬性可以設置為false表示自動裝備忽略Bean的資格。
1.1.3 constructor自動裝配
不需要<constructor-arg>元素,autowire為constructor。和byType有相同的局限性,也是按照類型去匹配的,一個構造器參數(shù)對應多個Bean,還有一個Bean對應多個構造器。
1.2 默認自動裝配
如果所有的bean都按照同一類型自動裝配,可以再<beans>元素中加default-autowire屬性。這個屬性默認為none,表示不使用自動裝配??梢栽O置為byName等類型。<bean>中的autowire會覆蓋default-autowire屬性。<property>會覆蓋自動裝配的值。
autowire=“constructor”時,不能與<constructor-arg>同時存在。其他類型可以于<property>同時存在。
2. 使用注解裝配
spring容器是默認禁用注解裝配的。要啟動,最簡單的就是context命名空間的<context:annotation-config/>
1.spring自帶的@Autowired注解2.JSR-330的@Inject注解
3.JSR-250的@Resource注解
2.1 @Autowired
有了這個注解,spring會按byType自動裝配。這個注解可以加在setter方法上,還可以加在需要自動裝配Bean的任意方法上,還可以加在構造器上。這個注解可以直接加在屬性上,并刪除setter方法。
這個注解必須只能有一個Bean匹配到注解的參數(shù)或屬性中。沒有匹配Bean或匹配多個Bean會有問題。
2.1.1可選的自動裝配
默認情況下,這個注解標識的屬性或參數(shù)必須是可裝配的。沒有Bean裝配到,就會報NoSuchBeanDefinitionException。這個時候可以設置required=false來設置自動裝配是可選的。沒有匹配到Bean就會為null。
@Autowired(required=false)private A a; required可以用于@Autowired使用的任何地方,但是在構造器中,只能有一個構造器是required為true,其他都要設置為false。當@Autowired標注多個構造器時,spring會從滿足條件的構造器中選擇入參最多的構造器。2.1.2限定歧義性的依賴 有可能spring找到了多個滿足條件的Bean,可以使用@Qualifier注解。
@Autowired@Qualifier("a")//指定a,默認從id找private A a; 相當于把byType轉為了byName??s小了自動裝配Bean的范圍。還可以在Bean中聲明<bean class="A"> <qualifier value="a"/>//可以限定這個Bean為a</bean>@Qualifier("a")//可以限定這個Bean為aclass A implement B{} @Autowired是減少spring xml配置的一種方式。但是使用它的類會引入spring的特定依賴。2.2 @Inject
@Injectprivate A a; 這個注解和@Autowired一樣可以自動裝配,可以裝配屬性,方法,構造器。但是沒有required屬性所以裝配的Bean必須存在,不存在會報錯。2.2.1限定@Inject所標注的屬性
@Autowired的@Qualifier與@Inject的@Named對應
@Inject@Named("a")private A a; @Qualifier注解縮小Bean的選擇范圍(默認使用Bean的id),@Named通過Bean的Id標識可選擇的Bean。2.3在注解注入中使用表達式
@Value可以裝配簡單值。
@Value("jack")//這里面是一個表達式private String name;@Value("#{abc.name}")private String name;3.自動檢測Bean<context:component-scan>除了完成<context:annotation-config>一樣的工作外,還允許Spring自動檢測Bean和定義Bean。
<context:component-scan//替代了<context:annotation-config>base-package="包">//會掃描指定的包及其子包,并找出能夠自動注冊的spring Bean </context:component-scan>3.1為自動檢測標注Bean
默認情況下<context:component-scan>查找使用構造型注解所標注的類。
1.@Component:通用的構造型注解,表示該類為spring組件
2.@Controller:表示該類定義為spring mvc controller
3.@Repository:表示該類為數(shù)據(jù)倉庫。
4.@Service:表示該類定義為服務
5.使用@Component標識的任意自定義注解
3.2過濾組件掃描
<context:component-scan>下面還有子元素<context:include-filter>和<context:exclude-filter>。只是用<context:component-scan>的情況下,spring只會去找基于注解的組件。但是還要包含一個沒有注解的接口的所有實現(xiàn)類要怎么辦。就是用<context:include-filter>
<context:component-scanbase-package="包"> <context:include-filter type="assignable" expression="xxx.abc"/></context:component-scan>type的5中類型1.annotation:掃面指定注解所標注的類,通過expression指定注解。
2.assignable:掃面派生于expression指定類型的哪些類。
3.aspectj:掃面與expression指定的aspectJ表達式匹配的類
4.custom:指定expression使用的自定義TypeFilter實現(xiàn)類。
5.regex:正則匹配的類。
4 使用spring基于java的配置
4.1 創(chuàng)建基于Java的配置
<context:component-scan>也會自動加載使用@Configuration注解所標注的類。
4.2 定義一個配置類
@Configurstion標注的類相當于<Beans>元素。可以包含一個或多個Bean。這些Bean的定義是使用@Bean注解來標注的方法。
4.3 聲明一個簡單Bean
@Bean public A get(){ return new B();} @Bean告知spring返回一個對象,該對象應該被注冊為spring上下文的一個Bean。方法名為Bean的id。 相對于xml配置來說的一個優(yōu)點就是,xml是用string類型配置的,編譯期無法檢查。如果重命名了一個類,或許會完了修改xml配置。4.4 使用spring的基于Java的配置進行注入
簡單值注入:
@Beanpublic A get(){ return new B(12);}@Beanpublic A get(){ B b = new B(); b.setName("jack"); return B;}引用注入:@Beanpublic A get(){ return new B();}@Beanpublic C set(){ return new C(get());}這里調用get()不會調用get()方法而是調用spring上下文中的Bean。
新聞熱點
疑難解答