概述
對於在容器中的bean而言, 它的工作可能依賴於其他Bean, 比如一臺電腦的工作依賴於鼠標,鍵盤,屏幕和主機. 當我們對每一個Bean完成初始化時候, 需要確定一種裝配方式, 將它所依賴的Bean注入進去.
Spring提供了三種依賴裝配方案:
- 通過XML來顯式指定裝配值.
- 通過JavaConfig進行裝配.
- 通過自動裝配機制.
通過XML顯式配置裝配
使用使用XML來顯式裝配時候, 我們又可以選擇三種方法:
- 通過setter來注入屬性值.
- 通過構造函數來注入屬性值.
- 通過Factory對象來直接注入Bean.
提示: 如果Java中沒有任何構造函數, 則編譯會自動生成一個默認的構造函數.
在XML中使用Setter來實現依賴注入
採用setter注入需要有兩個前提:
- 類需要有的無參構造函數.
- 類需要有對屬性的設置方法setXxx.
Java代碼:
public class Keyboard {
private String name;
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Keyboard{" +
"name='" + name + '\'' +
'}';
}
}
// 電腦
public class Computer {
private String name;
private Keyboard keyboard;
public void setName(String name) {
this.name = name;
}
public void setKeyboard(Keyboard keyboard) {
this.keyboard = keyboard;
}
@Override
public String toString() {
return "Computer{" +
"name='" + name + '\'' +
", keyboard=" + keyboard +
'}';
}
}
public static void main(String[] args) {
String path = "classpath:/application-di-computer.xml";
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(path);
Keyboard keyboard = context.getBean(lab.anoper.ioc.di.computer.component.Keyboard.class);
System.out.println(keyboard);
Computer computer = context.getBean(lab.anoper.ioc.di.computer.component.Computer.class);
System.out.println(computer);
}
bean定義文件:
<!--通過屬性注入-->
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
default-autowire="byName">
<bean id="hpKeyboard" class="lab.anoper.ioc.di.computer.component.Keyboard">
<!-- 惠普鍵盤 -->
<property name="name" value="HP"/>
</bean>
<bean id="computer" class="lab.anoper.ioc.di.computer.component.Computer">
<property name="name" value="Walter"/>
<property name="keyboard" ref="hpKeyboard"/>
</bean>
</beans>
輸出結果:
Keyboard{name='HP'}
Computer{name='Walter', keyboard=Keyboard{name='HP'}}
在XML中使用構造方法注入
使用構造函數注入需要有一個前提: 有相應的構造函數. 如果我們使用第三方時候, 並沒有提供setXxx方法時候, 可以使用構造函數注入.
java代碼:
public class Keyboard {
private String name;
public Keyboard(String name) {
this.name = name;
}
@Override
public String toString() {
return "Keyboard{" +
"name='" + name + '\'' +
'}';
}
}
public class Computer {
private String name;
private Keyboard keyboard;
public Computer(String name, Keyboard keyboard) {
this.name = name;
this.keyboard = keyboard;
}
@Override
public String toString() {
return "Computer{" +
"name='" + name + '\'' +
", keyboard=" + keyboard +
'}';
}
}
public class DIDemo {
public static void main(String[] args) {
String path = "classpath:/application-di-computer-cons.xml";
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(path);
Keyboard keyboard = context.getBean(lab.anoper.ioc.di.computer.component.Keyboard.class);
System.out.println(keyboard);
Computer computer = context.getBean(lab.anoper.ioc.di.computer.component.Computer.class);
System.out.println(computer);
}
}
配置文件:
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
default-autowire="byName">
<bean id="hpKeyboard" class="lab.anoper.ioc.di.computer.component.Keyboard">
<constructor-arg value="HP"/>
</bean>
<bean id="computer" class="lab.anoper.ioc.di.computer.component.Computer">
<constructor-arg value="Walter"/>
<constructor-arg ref="hpKeyboard"/>
</bean>
</beans>
輸出結果:
Keyboard{name='HP'}
Computer{name='Walter', keyboard=Keyboard{name='HP'}}
使用JavaConfig顯式裝配依賴
如果要是用JavaConfig顯式裝配依賴, 則需要使用@Configuration
, @Bean
等註解.
- @Configuration: 用於指示這個類中存在一個或者多個bean, 並且這些bean可以由Spring容器管理.
- @Bean: 指示這個方法會產生一個可以由Spring容器管理的bean.
Java代碼:
@Configuration
public class ComputerConfig {
@Bean
public Keyboard keyboard () {
return new Keyboard("HP");
}
@Bean
public Computer computer() {
return new Computer("Walter", keyboard());
}
}
public class DIDemo {
public static void main(String[] args) {
String scanPackages = "lab.anoper.ioc.di.computer.config";
// 指定要掃描的包
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(scanPackages);
Computer computer = context.getBean("computer", lab.anoper.ioc.di.computer.component.Computer.class);
System.out.println(computer);
}
}
運行結果:
Computer{name='Walter', keyboard=Keyboard{name='HP'}}
使用自動裝配注入依賴
使用自動裝配主要依賴於autowired
註解來實現, 這個註解可以註解在屬性上, setter方法上或者構造函數上. 註解在setter上或者是屬性上, 最終將會採用setter注入方法.註解在構造函數上, 最終會採用構造函數注入方法.
需要使用到如下註解:
- @Component: 指示此類是一個"組件", 當自動掃描時候, 將會被視爲一個候選.
- @Autowired: 將構造函數,字段,setter方法或config方法標記爲由Spring的依賴項注入工具自動裝配.