基本條件:所有的類要被spring所管理才能進(jìn)行依賴注入
A. 依賴注入
我們以下面這個(gè)例子說(shuō)明如何進(jìn)行依賴注入:
代碼準(zhǔn)備:
interfaces:
/**
* 有機(jī)箱
*/
public interface IComputerCase {
public String sysComputerCaseName();
}
/**
* 鍵盤鼠標(biāo)
*/
public interface IKeyboard {
public String sysKeyboardName();
}
/**
* 顯示器
*/
public interface IMonitor {
public String sysMonitorName();
}
entity:
public class Acer implements IMonitor {
public String sysMonitorName() {
return "宏基";
}
}
public class BenQ implements IMonitor {
public String sysMonitorName() {
return "明基";
}
}
public class Bubalus implements IComputerCase {
public String sysComputerCaseName() {
return "大水牛";
}
}
public class GoldenField implements IComputerCase {
public String sysComputerCaseName() {
return "金和田";
}
}
public class Logitech implements IKeyboard {
public String sysKeyboardName() {
return "羅技";
}
}
public class Rapoo implements IKeyboard {
public String sysKeyboardName() {
return "雷柏";
}
}
1.使用set注入(最常用的方式)
通過setxx方法注入:property
1.1 提供相應(yīng)要注入的類的setter
public class Computer1 {
private IComputerCase computerCase;
private IKeyboard keyboard;
private IMonitor monitor;
public IComputerCase getComputerCase() {
return computerCase;
}
//提供要注入的類的set方法
public void setComputerCase(IComputerCase computerCase) {
this.computerCase = computerCase;
}
public IKeyboard getKeyboard() {
return keyboard;
}
//提供要注入的類的set方法
public void setKeyboard(IKeyboard keyboard) {
this.keyboard = keyboard;
}
public IMonitor getMonitor() {
return monitor;
}
//提供要注入的類的set方法
public void setMonitor(IMonitor monitor) {
this.monitor = monitor;
}
}
1.2 在配置文件中注入
??name中的值會(huì)在Computer對(duì)象中調(diào)用setXX方法來(lái)注入(所以方法名稱不能變)斑司。比如注入name="computerCase"在具體注入時(shí)會(huì)回調(diào)用setComputerCase來(lái)完成注入神妹。ref="ComputerCase1"表示是配置文件中的bean中所創(chuàng)建的ComputerCase1的id僻肖。
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="ComputerCase1" class="com.IOCExercise.entity.Bubalus"/>
<bean id="ComputerCase2" class="com.IOCExercise.entity.GoldenField"/>
<bean id="Keyboard1" class="com.IOCExercise.entity.Logitech"/>
<bean id="Keyboard2" class="com.IOCExercise.entity.Rapoo"/>
<bean id="Monitor1" class="com.IOCExercise.entity.Acer"/>
<bean id="Monitor2" class="com.IOCExercise.entity.BenQ"/>
<bean id="Computer1" class="com.IOCExercise.test.Computer1">
<!--向Computer1注入computerCase-->
<property name="computerCase" ref="ComputerCase1" />
<!--向Computer1注入keyboard-->
<property name="keyboard" ref="Keyboard1" />
<!--向Computer1注入monitor-->
<property name="monitor" ref="Monitor1" />
</bean>
</beans>
1.3 測(cè)試
public class Computer1SetterTest {
public static void main(String[] args) {
//以ApplicationContext方式
ApplicationContext context=
new ClassPathXmlApplicationContext("bean1.xml");
Computer1 aComputer1=(Computer1)context.getBean("Computer1");
System.out.println("computer1's computercase:"+aComputer1.getComputerCase().sysComputerCaseName());
System.out.println("computer1's keyboard:"+aComputer1.getKeyboard().sysKeyboardName());
System.out.println("computer1's monitor:"+aComputer1.getMonitor().sysMonitorName());
}
2. 基于構(gòu)造函數(shù)的注入(了解)
通過構(gòu)造函數(shù)注入:constructor-arg
這種方式的注入是指帶有參數(shù)的構(gòu)造函數(shù)注入,如果未設(shè)置對(duì)象的set方法,所以就不能支持第一種注入方式惹谐。這里的注入方式是在構(gòu)造函數(shù)中注入碾篡,也就是說(shuō)在創(chuàng)建Computer2 對(duì)象時(shí)要將computerCase、keyboard和monitor這三個(gè)參數(shù)值傳進(jìn)來(lái)蹂喻。
2.1 提供相應(yīng)要注入的類的構(gòu)造方法
public class Computer2 {
public IComputerCase computerCase;
public IKeyboard keyboard;
public IMonitor monitor;
public Computer2(IComputerCase computerCase,IKeyboard keyboard,IMonitor monitor)
{
this.computerCase = computerCase;
this.keyboard = keyboard;
this.monitor = monitor;
}
}
2.2 在配置文件中注入
??在XML文件中同樣不用<property>的形式葱椭,而是使用<constructor-arg>標(biāo)簽,ref屬性同樣指向其它<bean>標(biāo)簽的name屬性:
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="ComputerCase1" class="com.IOCExercise.entity.Bubalus"/>
<bean id="ComputerCase2" class="com.IOCExercise.entity.GoldenField"/>
<bean id="Keyboard1" class="com.IOCExercise.entity.Logitech"/>
<bean id="Keyboard2" class="com.IOCExercise.entity.Rapoo"/>
<bean id="Monitor1" class="com.IOCExercise.entity.Acer"/>
<bean id="Monitor2" class="com.IOCExercise.entity.BenQ"/>
<bean id="Computer2" class="com.IOCExercise.test.Computer2">
<constructor-arg ref="ComputerCase2"/>
<constructor-arg ref="Keyboard2"/>
<constructor-arg ref="Monitor2"/>
</bean>
</beans>
當(dāng)構(gòu)造函數(shù)有多個(gè)參數(shù)時(shí)口四,可以使用constructor-arg標(biāo)簽的index屬性孵运,index屬性的值從0開始。下面是設(shè)置index蔓彩,就是參數(shù)位置:
<bean id="Computer2" class="com.IOCExercise.test.Computer2">
<constructor-arg index="0" ref="ComputerCase2"/>
<constructor-arg index="1" ref="Keyboard2"/>
<constructor-arg index="2" ref="Monitor2"/>
</bean>
2.3 測(cè)試
public class Computer2ConsTest {
public static void main(String[] args) {
//以ApplicationContext方式
ApplicationContext context=
new ClassPathXmlApplicationContext("bean1.xml");
Computer2 aComputer2=(Computer2)context.getBean("Computer2");
System.out.println("computer2's computercase:"+aComputer2.computerCase.sysComputerCaseName());
System.out.println("computer2's keyboard:"+aComputer2.keyboard.sysKeyboardName());
System.out.println("computer2's monitor:"+aComputer2.monitor.sysMonitorName());
}
B. 屬性注入和自動(dòng)注入
1. 屬性注入
以下面的例子說(shuō)明如何進(jìn)行屬性注入:
![Upload Paste_Image.png failed. Please try again.]
Classes類:
public class Classes {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Student類:
public class Student {
//姓名
private String name;
//學(xué)號(hào)
private int sno;
//班級(jí)
private Classes classes;
//課程分?jǐn)?shù)
private double[] score;
//課程列表
private List<String> course;
private Set<String> hobby;
private Map other;
//setter治笨、getter
}
bean.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" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="Classes3" class="com.IOCExercise.entity.Classes">
<property name="name" value="軟件R3班" />
</bean>
<bean id="Student" class="com.IOCExercise.entity.Student">
<!--通過value可以注入一個(gè)基本數(shù)據(jù)類型-->
<property name="name" value="zoyoto" />
<property name="sno" value="26" />
<!--引用Spring中定義的classes對(duì)象-->
<property name="classes" ref="Classes3" />
<!--注入數(shù)組-->
<property name="score">
<array>
<value>91</value>
<value>88</value>
</array>
</property>
<!--注入list-->
<property name="course">
<list>
<value>語(yǔ)文</value>
<value>數(shù)學(xué)</value>
</list>
</property>
<!--注入Set-->
<property name="hobby">
<set>
<value>畫畫</value>
<value>羽毛球</value>
</set>
</property>
<!--注入Map-->
<property name="other">
<map>
<entry key="beijing" value="北京"></entry>
<entry key="guangzhou" value="廣州" ></entry>
</map>
</property>
</bean>
</beans>
2. 自動(dòng)注入(一般不使用)
- byName是根據(jù)set的名稱注入的,如果名稱不對(duì)就無(wú)法注入(默認(rèn)情況)
- byType是根據(jù)類型來(lái)注入的赤嚼,和名稱無(wú)關(guān)旷赖,如果一個(gè)類中有兩個(gè)相同類型的對(duì)象則無(wú)法注入。
如果要使用一般使用byName:
C. 基于annotation的注入
使用@Resource更卒、@Autowired等孵、@Repository、@Service蹂空、@Controller 和 @Component可以將類標(biāo)識(shí)為 Bean俯萌。
annotation介紹
@Resource
??@Resource就相當(dāng)于application.getBean()方法。@Resource有兩個(gè)中重要的屬性:name和type 上枕,而Spring將@Resource注解的name屬性解析為bean的名字咐熙,而type屬性則解析為bean的類型。所以如果使用name屬性姿骏,則使用byName的自動(dòng)注入策略糖声,而使用type屬性時(shí)則使用 byType自動(dòng)注入策略。如果既不指定name也不指定type屬性,這時(shí)將通過反射機(jī)制使用byName自動(dòng)注入策略蘸泻。
@Autowired
??@Autowired作用和@Resource一樣琉苇,但@Autowired默認(rèn)按類型裝配(這個(gè)注解是屬業(yè)spring的),默認(rèn)情況下必須要求依賴對(duì)象必須存在悦施,如果要允許null 值并扇,可以設(shè)置它的required屬性為false,如:@Autowired(required=false) 抡诞,如果我們想使用名稱裝配可以結(jié)合@Qualifier注解進(jìn)行使用,如下:
@Autowired()
@Qualifier("baseDao")
private BaseDao baseDao;
@Component
??是一個(gè)泛華的概念昼汗,僅僅表示一個(gè)組件肴熏,可以作用于任何層次顷窒。
@Repository
??只能標(biāo)注在DAO層,這是因?yàn)樵撟⒔獾淖饔貌恢皇菍㈩愖R(shí)別為Bean鞋吉,同時(shí)它還能將所標(biāo)注的類中拋出的數(shù)據(jù)訪問異常封裝為Spring的數(shù)據(jù)訪問異常類型
@Service
??通常作用在業(yè)務(wù)層,但是目前該功能與@Component相同谓着。
@Controller
??通常作用在控制層,但是目前該功能與@Component相同赊锚。
1.設(shè)置bean.xml的schema
2.在類上面設(shè)置