# 裝配Spring Bean

裝配Spring Bean

目標(biāo):

  1. 掌握3種依賴注入的方式

  2. 掌握如何使用XML裝配Bean

  3. 掌握如何使用注解方式裝配Bean及消除歧義

  4. 掌握如何使用profile 和條件裝配Bean

  5. 掌握Bean 的作用域

  6. 了解Spring EL的簡(jiǎn)易使用

依賴注入的3種方式:

  • 構(gòu)造器注入

  • setter注入

  • 接口注入

構(gòu)造器注入:

構(gòu)造器注入依賴于構(gòu)造方法實(shí)現(xiàn),而構(gòu)造方法可以是有參數(shù)或是無(wú)參數(shù)的,在大部分的情況下,我們都是通過(guò)類的構(gòu)造器方法來(lái)創(chuàng)建類的對(duì)象,Spring也可以采用反射的方式,通過(guò)構(gòu)造方法來(lái)完成注入,這就是構(gòu)造器注入的原理。

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n26" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">package com.ssm.chapter9.pojo;

public class Role {
private Long id;
private String roleName;
private String note;

public Role(String roleName, String note) {
this.roleName = roleName;
this.note = note;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getRoleName() {
return roleName;
}

public void setRoleName(String roleName) {
this.roleName = roleName;
}

public String getNote() {
return note;
}

public void setNote(String note) {
this.note = note;
}

}
</pre>

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n27" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><bean id="role_1" class="com.ssm.chapter9.pojo.Role">
<constructor-arg index="0" value="高級(jí)工程師" />
<constructor-arg index="1" value="重要人員" />
</bean></pre>

constructor-arg元素用于定義類構(gòu)造方法的參數(shù),其中index用于定義參數(shù)的位置,而value則是設(shè)置值。

這個(gè)注入比較簡(jiǎn)單,但無(wú)法應(yīng)用大量參數(shù)的程式

使用setter注入:

setter注入是Spring中最主流注入方式,它利用Java Bean規(guī)范所定義的setter方法來(lái)完成注入,靈活且可讀性高。

首先把構(gòu)造方法聲明為無(wú)參數(shù)的,然后使用setter注入為其設(shè)置對(duì)應(yīng)的值,其實(shí)是通過(guò)Java反射技術(shù)得以實(shí)現(xiàn)。

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n33" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">package com.ssm.chapter9.pojo;

public class Role {
private Long id;
private String roleName;
private String note;

public Role() {

}
public Role(String roleName, String note) {
this.roleName = roleName;
this.note = note;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getRoleName() {
return roleName;
}

public void setRoleName(String roleName) {
this.roleName = roleName;
}

public String getNote() {
return note;
}

public void setNote(String note) {
this.note = note;
}

}</pre>

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n34" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><bean id="role2" class="com.ssm.chapter9.pojo.Role">
<property name="roleName" value="高級(jí)工程師" />
<property name="note" value="重要人員" />
</bean></pre>

這樣Spring就會(huì)通過(guò)反射調(diào)用沒(méi)有參數(shù)的構(gòu)造方法生成對(duì)象,同時(shí)通過(guò)反射對(duì)應(yīng)的setter注入配置的值了,這種方式是Spring最主要的方式。

接口注入:

接口注入主要來(lái)自外界

裝配Bean概述

Spring 中提供3中方法進(jìn)行配置:

  • 在xml中顯示配置。

  • 在Java的接口和類中實(shí)現(xiàn)配置。

  • 隱式配置的接口發(fā)現(xiàn)機(jī)制和自動(dòng)裝配原則

3種方式優(yōu)先級(jí):

  1. 基于約定優(yōu)于配置的原則,最優(yōu)先的應(yīng)該是通過(guò)隱式Bean的發(fā)現(xiàn)機(jī)制和自動(dòng)裝配的原則.這樣的好處是減少程序開發(fā)者的決定權(quán),簡(jiǎn)單又不失靈活。

  2. 在沒(méi)有辦法使用自動(dòng)裝配原則的情況下應(yīng)該優(yōu)先考慮Java接口和類中實(shí)現(xiàn)配置,這樣的好處是避免xml配置的泛濫,也更為容易。這種場(chǎng)景典型的例子是一個(gè)父類有多個(gè)子類,比如學(xué)生類有兩個(gè)子類:男生類和女生類,通過(guò)IoC容器初始化一個(gè)學(xué)生類,容器將無(wú)法知道使用哪個(gè)子類去初始化,這個(gè)時(shí)候可以使用Java的注解配置去指定。

  3. 在上述方法無(wú)法使用的情況下,那么只能選擇xml去配置Spring IoC容器。由于現(xiàn)實(shí)工作中常常用到第三方的類庫(kù),有些類 并不是我們開發(fā)的,我們無(wú)法修改里面的代碼,這個(gè)時(shí)候就通過(guò)xml的方式配置使用了。

通過(guò)XML配置配置裝配Bean

xml對(duì)于剛接觸Spring IoC容器的人來(lái)說(shuō)更為清晰明了,使用xml裝配Bean需要定義對(duì)應(yīng)的Spring Bean的元素。

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n57" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><?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-4.0.xsd">

</beans></pre>

裝配簡(jiǎn)易值

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n59" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><bean id="role2" class="com.ssm.chapter9.pojo.Role">
<property name="id" value="1" />
<property name="roleName" value="高級(jí)工程師" />
<property name="note" value="重要人員" />
</bean></pre>

  • id="role2" id屬性是spring找到的一個(gè)Bean的編號(hào),不過(guò)id不是一個(gè)必須的屬性,如果沒(méi)有聲明它,那么Spring將會(huì)采用“全限定名#{number}”的格式編號(hào)。com.ssm.chapter9.pojo.Role#0==bean id="role2" class="com.ssm.chapter9.pojo.Role"

  • class顯然是一個(gè)類的全限定名

  • property元素是定義類的屬性,其中name屬性定義的是屬性的名稱,而value是其值。

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n67" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> <bean id="source" class="com.ssm.chapter9.pojo.Source">
<property name="fruit" value="橙汁" />
<property name="sugar" value="少糖" />
<property name="size" value="大杯" />
</bean>

<bean id="juiceMaker2" class="com.ssm.chapter9.pojo.JuiceMaker2">
<property name="beverageShop" value="貢茶" />
<property name="source" ref="source" />
</bean></pre>

裝配集合:

有些時(shí)候要一些復(fù)雜的裝配工作,比如Set,Map,List,Array,Properties等。先定義Bean

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n71" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">package com.ssm.chapter10.pojo;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class ComplexAssembly {

private Long id;
private List<String> list;
private Map<String, String> map;
private Properties props;
private Set<String> set;
private String[] array;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public List<String> getList() {
return list;
}

public void setList(List<String> list) {
this.list = list;
}

public Map<String, String> getMap() {
return map;
}

public void setMap(Map<String, String> map) {
this.map = map;
}

public Properties getProps() {
return props;
}

public void setProps(Properties props) {
this.props = props;
}

public Set<String> getSet() {
return set;
}

public void setSet(Set<String> set) {
this.set = set;
}

public String[] getArray() {
return array;
}

public void setArray(String[] array) {
this.array = array;
}

}</pre>

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n72" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><bean id="complexAssembly" class="com.ssm.chapter10.pojo.ComplexAssembly">
<property name="id" value="1" />
<property name="list">
<list>
<value>value-list-1</value>
<value>value-list-2</value>
<value>value-list-3</value>
</list>
</property>
<property name="map">
<map>
<entry key="key1" value="value-key-1" />
<entry key="key2" value="value-key-2" />
<entry key="key3" value="value-key-3" />
</map>
</property>
<property name="props">
<props>
<prop key="prop1">value-prop-1</prop>
<prop key="prop2">value-prop-2</prop>
<prop key="prop3">value-prop-3</prop>
</props>
</property>
<property name="set">
<set>
<value>value-set-1</value>
<value>value-set-2</value>
<value>value-set-3</value>
</set>
</property>
<property name="array">
<array>
<value>value-array-1</value>
<value>value-array-2</value>
<value>value-array-3</value>
</array>
</property>
</bean></pre>

  • List屬性為對(duì)應(yīng)的<list>元素進(jìn)行裝配,然后通過(guò)多個(gè)<value>元素設(shè)值。

  • Map屬性為對(duì)應(yīng)的<map>元素進(jìn)行裝配,然后通過(guò)多個(gè)<entry>元素設(shè)值,只是entry包含一個(gè)鍵(key)和一個(gè)值(value)的設(shè)值。

  • Properties屬性,為對(duì)應(yīng)的<Properties>元素進(jìn)行裝配,然后通過(guò)多個(gè)<Property>元素設(shè)值,只是property元素有一個(gè)必填屬性key,然后可以設(shè)值。

  • Set屬性為對(duì)應(yīng)的<set>元素進(jìn)行裝配,然后通過(guò)多個(gè)<value>元素設(shè)值.

  • 對(duì)于數(shù)組而言,<array>元素進(jìn)行裝配,然后通過(guò)多個(gè)<value>元素設(shè)值.

從上面看到對(duì)字符串的各個(gè)集合加載,但是有些時(shí)候可能需要更為復(fù)雜的裝載,比如一個(gè)List可以是一個(gè)系列類的對(duì)象,又如一個(gè)Map集合類,鍵可以是一個(gè)類的對(duì)象,而值也要是一個(gè)類的對(duì)象。

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n85" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">package com.ssm.chapter10.pojo;

public class Role {
private Long id;
private String roleName;
private String note;

public Role() {
}

public Role(Long id, String roleName, String note) {
this.id = id;
this.roleName = roleName;
this.note = note;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getRoleName() {
return roleName;
}

public void setRoleName(String roleName) {
this.roleName = roleName;
}

public String getNote() {
return note;
}

public void setNote(String note) {
this.note = note;
}

}
</pre>

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n86" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">package com.ssm.chapter10.pojo;

public class User {
private Long id;
private String userName;
private String note;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public String getNote() {
return note;
}

public void setNote(String note) {
this.note = note;
}

}
</pre>

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n87" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">package com.ssm.chapter10.pojo;

import java.util.List;
import java.util.Map;
import java.util.Set;

public class UserRoleAssembly {

private Long id;
private List<Role> list;
private Map<Role, User> map;
private Set<Role> set;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public List<Role> getList() {
return list;
}

public void setList(List<Role> list) {
this.list = list;
}

public Map<Role, User> getMap() {
return map;
}

public void setMap(Map<Role, User> map) {
this.map = map;
}

public Set<Role> getSet() {
return set;
}

public void setSet(Set<Role> set) {
this.set = set;
}

}
</pre>

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n88" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><bean id="role1" class="com.ssm.chapter10.pojo.Role">
<property name="id" value="1" />
<property name="roleName" value="role_name_1" />
<property name="note" value="role_note_1" />
</bean>

<bean id="role2" class="com.ssm.chapter10.pojo.Role">
<property name="id" value="2" />
<property name="roleName" value="role_name_2" />
<property name="note" value="role_note_2" />
</bean>

<bean id="user1" class="com.ssm.chapter10.pojo.User">
<property name="id" value="1" />
<property name="userName" value="user_name_1" />
<property name="note" value="role_note_1" />
</bean>

<bean id="user2" class="com.ssm.chapter10.pojo.User">
<property name="id" value="2" />
<property name="userName" value="user_name_2" />
<property name="note" value="role_note_1" />
</bean>

<bean id="userRoleAssembly" class="com.ssm.chapter10.pojo.UserRoleAssembly">
<property name="id" value="1" />
<property name="list">
<list>
<ref bean="role1" />
<ref bean="role2" />
</list>
</property>
<property name="map">
<map>
<entry key-ref="role1" value-ref="user1" />
<entry key-ref="role2" value-ref="user2" />
</map>
</property>
<property name="set">
<set>
<ref bean="role1" />
<ref bean="role2" />
</set>
</property>
</bean></pre>

這里定義了兩個(gè)角色Bean(role1和role2)和兩個(gè)用戶Bean(user1和user2),他們和之前定義沒(méi)有什么不同,只是后面的定義略微不同而已。

  • List屬性為對(duì)應(yīng)的<list>元素定義注入,然后使用多個(gè)<ref>元素的Bean屬性去引用之前定義好的Bean。

  • Map屬性使用<map>元素定義注入,然后使用多個(gè)<entry>元素的key-ref屬性去引用之前定義好的Bean作為鍵,而用value-ref屬性去引用之前定義好的Bean作為值。

  • Set屬性使用<set>元素定義注入,然后使用多個(gè)<ref>元素的Bean屬性去引用之前定義好的Bean

命名空間裝配

Spring還提供對(duì)應(yīng)的命名空間的定義,只是在使用命名空間的時(shí)候要先引入對(duì)應(yīng)的命名空間和xml模式。

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="xml" cid="n100" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><beans xmlns="http://www.springframework.org/schema/beans"
xmlns:c="http://www.springframework.org/schema/c" xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util" 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/util http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="role1" class="com.ssm.chapter10.pojo.Role"
c:_0="1" c:_1="role_name_1" c:_2="role_note_1" />
<bean id="role2" class="com.ssm.chapter10.pojo.Role"
p:id="2" p:roleName="role_name_2" p:note="role_note_2" />
<bean id="user1" class="com.ssm.chapter10.pojo.User"
p:id="1" p:userName="role_name_1" p:note="user_note_1" />
<bean id="user2" class="com.ssm.chapter10.pojo.User"
p:id="2" p:userName="role_name_2" p:note="user_note_2" />

<util:list id="list">
<ref bean="role1" />
<ref bean="role2" />
</util:list>

<util:map id="map">
<entry key-ref="role1" value-ref="user1" />
<entry key-ref="role2" value-ref="user2" />
</util:map>

<util:set id="set">
<ref bean="role1" />
<ref bean="role2" />
</util:set>

<bean id="userRoleAssembly" class="com.ssm.chapter10.pojo. UserRoleAssembly"
p:id="1" p:list-ref="list" p:map-ref="map" p:set-ref="set" />
</beans></pre>

xmlns:c="http://www.springframework.org/schema/c"

xmlns:p="http://www.springframework.org/schema/p"

xmlns:util="http://www.springframework.org/schema/util"

  • 注意加粗的代碼,它們定義了XML的命名空間,這樣才能在內(nèi)容里面使用p和c這樣的前綴定義

  • id為role1的角色定義,c:0代表構(gòu)造方法的第一個(gè)參數(shù),c:1代表的是第2個(gè),c:_2代表的是第3個(gè),以此類推。

  • id為role2的角色定義,p代表引用屬性,其中p:id=“2”以2為值,使用setId方法設(shè)置,roleName,note屬性也是一樣的道理

通過(guò)注解裝配Bean

從上面的例子已知如何使用XML的方式去裝配Bean,但更多的時(shí)候已經(jīng)不推薦使用XMl的方式去裝配Bean,更多時(shí)候回考慮使用注解(annotation)的方式去裝配Bean,使用注解方式可以減少xml的配置,注解功能更為強(qiáng)大,它既能實(shí)現(xiàn)XML的功能,也提供了自動(dòng)裝配的功能,采用了自動(dòng)裝配后,程序員所需要做的決斷就少了,更有利對(duì)程序的開發(fā),這就是“約定優(yōu)于配置”的開發(fā)原則。

在Spring中,它提供了兩種方式來(lái)讓Spring IoC容器發(fā)現(xiàn)Bean。

  • 組件掃描:通過(guò)定義資源的方式,讓Spring IoC容器掃描對(duì)應(yīng)的包,從而把Bean裝配進(jìn)來(lái)。

  • 自動(dòng)裝配:通過(guò)注解定義,使得一些依賴關(guān)系可以通過(guò)注解完成。

通過(guò)掃描和自動(dòng)裝配,大部分的工程都可以用Java配置完成,而不是xml,可以有效減少配置和引入大量xml。

如果系統(tǒng)存在多個(gè)公共的配置文件(多個(gè)properties和xml文件)或第三方資源,使用xml配置會(huì)更加明確。

以注解為主,以xml配置為輔。

使用@Component裝配Bean

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n123" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">package com.zw.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component(value = "role")
public class Role {
@Value("1")
private Long id;
@Value("role_name_1")
private String roleName;
@Value("role_note_1")
private String note;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getRoleName() {
return roleName;
}

public void setRoleName(String roleName) {
this.roleName = roleName;
}

public String getNote() {
return note;
}

public void setNote(String note) {
this.note = note;
}

}
</pre>

注意註解@Component(value = "role"),@Value("1")

  • 註解@Component代表Spring IoC會(huì)把這個(gè)類掃描生成Bean實(shí)例,而其中的value屬性代表在Spring中的id,這就相當(dāng)于XML方式定義的Bean的id,(<bean id="role_1"class="com.ssm.chapter9.pojo.Role">也可以簡(jiǎn)寫成@Component("role"),甚至直接寫成@Componen,對(duì)于不寫的,Spring IoC容器就默認(rèn)類名,但是以首字母小寫的形式作為id,為其生成對(duì)象,配置到容器中。

  • 注解@Value代表的是值得注入,這里只是簡(jiǎn)單注入一些值,其中id是一個(gè)long型,注入的時(shí)候Spring會(huì)為其轉(zhuǎn)換類型。

Spring IoC掃描類

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n131" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">package com.zw.pojo;

import org.springframework.context.annotation.ComponentScan;

@ComponentScan
public class PojoConfig {

}
</pre>

注意:package com.zw.pojo; @ComponentScan

  • 包名和代碼清單需要一致(package com.zw.pojo;)

  • @ComponentScan代表進(jìn)行掃描,默認(rèn)是掃描當(dāng)前包的路徑,POJO的包名和它保持一致才能掃描,否則沒(méi)有的。

測(cè)試:

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n139" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">package com.zw.main;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.zw.pojo.PojoConfig;
import com.zw.pojo.Role;

public class Demo1Main {

public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext context = new AnnotationConfigApplicationContext(PojoConfig.class);
Role role=context.getBean(Role.class);
System.out.println(role.getId());
}

}
</pre>

此處有兩個(gè)明顯的弊端:

  1. 對(duì)于@ComponentScan注解,它只掃描所在包的Java類,但是更多的時(shí)候真正需要的是可以掃描所指定的類

  2. 上面只是注入了一些簡(jiǎn)單的值,而沒(méi)有注入對(duì)象,同樣在現(xiàn)實(shí)的開發(fā)可以注入對(duì)象是十分重要的

@ComponentScan有兩個(gè)配置項(xiàng):

  1. basePackages:base Packages Package+s Package表示包,s表示多個(gè)包。

  2. basePackageClasses:base Package Classes Class+es Class表示類,es表示多個(gè)類。

驗(yàn)證@ComponentScan的兩個(gè)配置項(xiàng),首先定義一個(gè)接口RoleService

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n153" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">package com.zw.service;

import com.zw.pojo.Role;

public interface RoleService {
public void printRoleInfo(Role role);

}
</pre>

使用接口編寫一些操作類是Spring所推薦的,它可以將定義和實(shí)現(xiàn)分離,這樣就更為靈活。

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n155" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">package com.zw.service.impl;

import org.springframework.stereotype.Component;

import com.sun.org.apache.xerces.internal.impl.dv.dtd.IDDatatypeValidator;
import com.zw.pojo.Role;
import com.zw.service.RoleService;
@Component
public class RoleServiceImpl implements RoleService {

@Override
public void printRoleInfo(Role role) {
// TODO Auto-generated method stub
System.out.println("id="+role.getId());
System.out.println("roleName="+role.getRoleName());
System.out.println("note="+role.getNote());
}

}
</pre>

這里的@ComponentScan表明它是一個(gè)Spring所需要的Bean。而且也實(shí)現(xiàn)了對(duì)應(yīng)的RoleService接口所定義的printRoleInfo方法,

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n158" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">package com.zw.config;

import static org.springframework.test.web.client.match.MockRestRequestMatchers.content;

import org.springframework.context.annotation.ComponentScan;

import com.zw.pojo.Role;
import com.zw.service.impl.RoleServiceImpl;

@ComponentScan(basePackageClasses= {Role.class,RoleServiceImpl.class})//重構(gòu)項(xiàng)目使用它,便于報(bào)錯(cuò)讀取
//@ComponentScan(basePackages= {"com.zw.pojo.Role","com.zw.service"}) //項(xiàng)目?jī)?yōu)先使用它,可讀性比較好

public class ApplicationConfig {

}
</pre>

注意:

  • 這是對(duì)掃描包的定義,可以采用任意一個(gè)@ComponentScan去定義,也可以取消代碼中的注釋。

  • 如果采用多個(gè)@ComponentScan去定義對(duì)應(yīng)的包,但是每定義一個(gè)@ComponentScan,Spring就會(huì)產(chǎn)生一個(gè)新的對(duì)象,也就是所配置的Bean將會(huì)生成多個(gè)實(shí)例,這往往不是我們所需要的。

  • 對(duì)于已定義的basePackagesbasePackageClasses@ComponentScan,Spring會(huì)進(jìn)行專門的區(qū)分,也就是說(shuō)在同一個(gè)@ComponentScan中即使重復(fù)定義相同的包或者存在其子包的定義,也不會(huì)造成因一個(gè)Bean的多次掃描,而導(dǎo)致一次配置生成多個(gè)對(duì)象。

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n167" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">package com.zw.main;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.zw.config.ApplicationConfig;
import com.zw.pojo.PojoConfig;
import com.zw.pojo.Role;
import com.zw.service.RoleService;
import com.zw.service.impl.RoleServiceImpl;

public class Demo1Main {

public static void main(String[] args) {
// TODO Auto-generated method stub
test2();
}

private static void test1() {
ApplicationContext context = new AnnotationConfigApplicationContext(PojoConfig.class);
Role role=context.getBean(Role.class);
System.out.println(role.getId());
}
private static void test2() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
Role role=context.getBean(Role.class);
RoleService roleService=context.getBean(RoleService.class);
roleService.printRoleInfo(role);
context.close();

}

}
</pre>

自動(dòng)裝配--@Autowired:

前面提到兩個(gè)問(wèn)題之一就是沒(méi)有注入對(duì)象,關(guān)于這個(gè)問(wèn)題,在注解中略微有點(diǎn)復(fù)雜。大部分的情況下建議使用自動(dòng)裝配,因?yàn)榭梢詼p少配置的復(fù)雜度。前面的Spring學(xué)習(xí),Spring是先完成Bean的定義和生成,然后尋找需要注入的資源。

<pre mdtype="fences" cid="n170" lang="java" class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">package com.zw.service;

public interface RoleService2 {
public void printRoleInfo();

}
</pre>

Spring 推薦的接口方式,這個(gè)更靈活。因?yàn)閷⒍x和實(shí)現(xiàn)分離了。

<pre mdtype="fences" cid="n174" lang="java" class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">package com.zw.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.zw.pojo.Role;
import com.zw.service.RoleService2;
@Component("RoleService2")

public class RoleServiceImpl2 implements RoleService2 {
@Autowired
private Role role=null;

public Role getRole() {
return role;
}

public void setRole(Role role) {
this.role = role;
}

@Override
public void printRoleInfo() {
// TODO Auto-generated method stub
System.out.println("id="+role.getId());
System.out.println("roleName="+role.getRoleName());
System.out.println("note="+role.getNote());
}

}
</pre>

@Autowired

private Role role=null;

@Autowired注解,表示在Spring IoC定位所有的Bean后,這個(gè)字段需要按類型注入,這樣IoC容器就會(huì)尋找資源,然后將其注入。

<pre mdtype="fences" cid="n176" lang="java" class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">package com.zw.main;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.zw.config.ApplicationConfig;
import com.zw.pojo.PojoConfig;
import com.zw.pojo.Role;
import com.zw.service.RoleService;
import com.zw.service.RoleService2;
import com.zw.service.impl.RoleServiceImpl;

public class Demo1Main {

public static void main(String[] args) {
// TODO Auto-generated method stub
test3();
}

private static void test1() {
ApplicationContext context = new AnnotationConfigApplicationContext(PojoConfig.class);
Role role=context.getBean(Role.class);
System.out.println(role.getId());
}
private static void test2() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
Role role=context.getBean(Role.class);
RoleService roleService=context.getBean(RoleService.class);
roleService.printRoleInfo(role);
context.close();

}

private static void test3() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
RoleService2 roleService = context.getBean(RoleService2.class);
roleService.printRoleInfo();
context.close();

}

}
</pre>

自動(dòng)裝配的歧視性(@Primary和@Qualifier):

@Autowired在一個(gè)接口有多個(gè)實(shí)現(xiàn)類的時(shí)候無(wú)法使用

<pre mdtype="fences" cid="n194" lang="java" class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">package com.zw.service.impl;

import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import com.zw.pojo.Role;
import com.zw.service.RoleService;
@Component("roleService3")
//@Primary //測(cè)試@Primary 一個(gè)接口存在多個(gè)實(shí)現(xiàn)類 區(qū)分優(yōu)先處理
public class RoleServiceImpl3 implements RoleService{

@Override
public void printRoleInfo(Role role) {
// TODO Auto-generated method stub
System.out.println("id ="+role.getId());
System.out.println(",roleName ="+role.getRoleName());
System.out.println("roleService3note ="+role.getNote());
}

}
</pre>

在新建一個(gè)RoleController類,它有個(gè)字段RoleService類型。

<pre mdtype="fences" cid="n201" lang="java" class="md-fences md-end-block ty-contain-cm modeLoaded md-focus" spellcheck="false" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">package com.zw.controlller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.zw.pojo.Role;
import com.zw.service.RoleService;
@Component
//Controlller 控制器
public class RoleControlller {
@Autowired
private RoleService roleService=null;
public void printRole(Role role) {
roleService.printRoleInfo(role);

}

}
</pre>

這里的字段 RoleService是一個(gè)RoleService接口類型。RoleService有兩個(gè)實(shí)現(xiàn)類。分別是RoleServiceImpl和RoleServiceImpl3,這個(gè)時(shí)候Spring IoC容器就會(huì)犯糊涂,無(wú)法判斷把那個(gè)對(duì)象注入進(jìn)來(lái),于是就會(huì)拋出異常。這樣@Autowired就失敗了。

//@Primary //測(cè)試@Primary 一個(gè)接口存在多個(gè)實(shí)現(xiàn)類 區(qū)分優(yōu)先處理

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

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

  • # 通過(guò)注解裝配Bean ## 使用@Component 裝配Bean - 定義一個(gè)`POJO`: ``` @Co...
    Cvencent閱讀 155評(píng)論 0 0
  • 裝配 Bean 的概述 前面已經(jīng)介紹了 Spring IoC 的理念和設(shè)計(jì),這一篇文章將介紹的是如何將自己開發(fā)的 ...
    我沒(méi)有三顆心臟閱讀 5,342評(píng)論 4 27
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,618評(píng)論 19 139
  • Spring bean 的裝配方式總的來(lái)說(shuō)有以下3種:基于xml配置文件的裝配、基于注解的裝配、基于命名空間的裝配...
    john_leventon閱讀 406評(píng)論 0 1
  • 本章的學(xué)習(xí)目標(biāo)看如下的思維導(dǎo)圖: 依賴注入 在實(shí)際環(huán)境中實(shí)現(xiàn)Ioc容器的方式主要分為:依賴查找和依賴注入二者關(guān)系 ...
    wtbook閱讀 431評(píng)論 0 4

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