學習Spring知識之前,A類中需要使用到B類的對象,我們會怎麼辦呢?
當A類需要使用到B類的資源的話,會直接在A類中創建B類的對象
學習Spring知識之後,A類中需要使用到B類的對象,我們會怎麼辦呢?
當A類需要使用到B類的資源的話,IOC/DI容器會先去獲得B類的實例(①)
IOC/DI容器再將B類的實例注入到A類中(②)
我們已經看到了容器存在的意義,就是先將程序內所有會使用到的資源全部獲取到,誰需要就再給誰!
這裏又提到了IOC和DI,那麼二者之間又有什麼區別呢?
什麼是IOC?
IOC(Inversion Of Control):控制反轉,意思就是將獲取資源的權利由應用程序轉變爲了Spring容器
什麼是DI?
DI( Dependency Injection):依賴注入,意思就是Spring容器獲取資源並將資源注入到應用程序中
二者的區別
二者是對同一件事情的不同描述,只是描述時所站的角度不同罷了
下面會介紹下依賴注入的幾種類型!
一.案例展示
1.測試準備
項目工程
2.代碼展示
***pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.howie</groupId>
<artifactId>springIOC_injection</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--導入Spring-context的jar包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
</dependencies>
</project>
***ComplexTypeInject.java
package com.howie.pojo;
import java.util.*;
/**
* @Author weihuanwen
* @Date 2019/8/14 23:49
* @Version 1.0
*/
public class ComplexTypeInject {
private String[] myStrs;
private List<String> myList;
private Set<String> mySet;
private Map<String,String> myMap;
private Properties myProps;
public String[] getMyStrs() {
return myStrs;
}
public void setMyStrs(String[] myStrs) {
this.myStrs = myStrs;
}
public List<String> getMyList() {
return myList;
}
public void setMyList(List<String> myList) {
this.myList = myList;
}
public Set<String> getMySet() {
return mySet;
}
public void setMySet(Set<String> mySet) {
this.mySet = mySet;
}
public Map<String, String> getMyMap() {
return myMap;
}
public void setMyMap(Map<String, String> myMap) {
this.myMap = myMap;
}
public Properties getMyProps() {
return myProps;
}
public void setMyProps(Properties myProps) {
this.myProps = myProps;
}
@Override
public String toString() {
return "ComplexTypeInject{" +
"myStrs=" + Arrays.toString(myStrs) +
", myList=" + myList +
", mySet=" + mySet +
", myMap=" + myMap +
", myProps=" + myProps +
'}';
}
}
***UserByConstructorInject.java
package com.howie.pojo;
/**
* @Author weihuanwen
* @Date 2019/8/14 23:48
* @Version 1.0
*/
public class UserByConstructorInject {
private String name;
private Integer age;
public UserByConstructorInject(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "UserByConstructorInject{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
***UserBySetInject.java
package com.howie.pojo;
/**
* @Author weihuanwen
* @Date 2019/8/14 23:45
* @Version 1.0
*/
public class UserBySetInject {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "UserBySetInject{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
***ApplicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--通過實體類的setter方法實現屬性值注入-->
<bean id="UserBySetInject" class="com.howie.pojo.UserBySetInject">
<!--使用property標籤完成實體類的set()操作-->
<property name="name" value="Jhon" />
<property name="age" value="28" />
</bean>
<!--通過構造方法實現屬性值注入-->
<bean id="UserByConstructorInject" class="com.howie.pojo.UserByConstructorInject">
<!--使用constructor標籤完成實體類構造方法屬性注入-->
<constructor-arg name="name" value="Lily" />
<constructor-arg name="age" value="30" />
</bean>
<!--實現複雜類型注入的配置-->
<bean id="ComplexTypeInject" class="com.howie.pojo.ComplexTypeInject">
<!--String[] myStrs-->
<property name="myStrs">
<array>
<value>孫悟空</value>
<value>菩提祖</value>
<value>紅孩兒</value>
</array>
</property>
<!--List<String> myList;-->
<property name="myList">
<list>
<value>浮誇</value>
<value>十年</value>
<value>揹包</value>
</list>
</property>
<!--Set<String> mySet;-->
<property name="mySet">
<set>
<value>若需</value>
<value>若即</value>
<value>若離</value>
</set>
</property>
<!--Map<String,String> myMap;-->
<property name="myMap">
<map>
<entry key="天" value="地" />
<entry key="雨" value="風" />
<entry key="大陸" value="長空" />
</map>
</property>
<!--Properties myProps;-->
<property name="myProps">
<props>
<prop key="1">未來</prop>
<prop key="2">現在</prop>
</props>
</property>
</bean>
</beans>
***MyTest.java
package com.howie;
import com.howie.pojo.ComplexTypeInject;
import com.howie.pojo.UserByConstructorInject;
import com.howie.pojo.UserBySetInject;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @Author weihuanwen
* @Date 2019/8/14 23:52
* @Version 1.0
*/
public class MyTest {
private ClassPathXmlApplicationContext cpxax;
@Before
public void execBefore(){
cpxax = new ClassPathXmlApplicationContext("ApplicationContext.xml");
}
@Test
public void testSetInject(){
UserBySetInject user = cpxax.getBean("UserBySetInject", UserBySetInject.class);
System.out.println(user);
}
@Test
public void testConstructorInject(){
UserByConstructorInject user = cpxax.getBean("UserByConstructorInject", UserByConstructorInject.class);
System.out.println(user);
}
@Test
public void testComplexInject(){
ComplexTypeInject cti = cpxax.getBean("ComplexTypeInject", ComplexTypeInject.class);
System.out.println(cti);
}
}
3.測試
①執行testSetInject()控制檯輸出
UserBySetInject{name='Jhon', age=28}
②執行testConstructorInject()控制檯輸出
UserByConstructorInject{name='Lily', age=30}
③執行testComplexInject()控制檯輸出
ComplexTypeInject{myStrs=[孫悟空, 菩提祖, 紅孩兒], myList=[浮誇, 十年, 揹包], mySet=[若需, 若即, 若離], myMap={天=地, 雨=風, 大陸=長空}, myProps={2=現在, 1=未來}}
二.總結
1.通過上面的案例,可以瞭解到如何實現下面的注入
- set注入
- 構造注入
- 複雜類型注入
2.爲什麼要是用Spring呢?
在一個大型的應用程序中必然包含很多的組件,組件之間互相調用,但是在運行時並非所有的組件都必須創建.在沒有Spring技術之前,A組件需要調用B組件時,就需要採取new或者getInstance的方式獲取B組件的實例,這樣就產生了組件A同組件B之間的耦合.隨着工程規模的擴大, N多組件間的耦合度越來越高,後期維護成本相當高.爲了減少這種耦合,Spring誕生了!
Spring框架基於BeanFactory,將模塊的配置信息(模塊根據需求創建)同模塊的配置參數(模塊不必讀取參數,Spring統一加載)統一管理.加入依賴注入(DI),Spring負責將模塊依賴度的其他模塊(push)推送進來,而不是自己去拉取(pull),所以是一個"控制反轉"(IOC)