1. 程式人生 > >二、Spring的依賴註入

二、Spring的依賴註入

成員 對比 over context strong () xsd beans 面向接口

Spring的依賴註入

1.理解依賴註入

(1)A對象需要調用B對象的方法,這種情形被稱為依賴註入,即A對象依賴B對象;依賴註入(DI)也被成為控制反轉(IoC);

(2)依賴註入的兩種方式:

  1)設值註入:IoC容器通過使用成員變量的setter方法來註入被依賴對象;

  2)構造註入:IoC容器通過使用構造器來註入被依賴的對象;

2.設置註入

(1)Bean與Bean之間的依賴關系由Spring管理,Spring采用setter方法為目標Bean註入所需要的值,這種註入方式被稱為設值註入;

(2)代碼

public interface Person {
    //定義一個使用斧頭的方法
public void useAxe(); }
public interface Axe {
    //Axe中定義一個chop()方法
    public String chop();
}
public class Chinese implements Person{
    private Axe axe;
    public void setAxe(Axe axe){
        this.axe = axe;
    }
    //實現Person接口的useAxe()方法
    @Override
    public void useAxe() {
        
// TODO Auto-generated method stub //調用axe的chop方法 //表明Person對象依賴於axe對象 System.out.println(axe.chop()); } }
public class StoneAxe implements Axe{

    @Override
    public String chop() {
        // TODO Auto-generated method stub
        return "石斧砍柴好慢";
        
    }

}
public
class SteelAxe implements Axe{ @Override public String chop() { // TODO Auto-generated method stub return "鋼斧砍柴真快"; } }
<?xml version="1.0" encoding="UTF-8"?>
<!-- Spring配置文件的根元素,使用spring-beans-4.0.xsd語義約束 -->
<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-4.0.xsd"
    >
    <!-- 配置chinese實例,其實現類是Chinese -->
    <bean id="chinese" class="test_2.Chinese">
        <!-- 驅動調用chinese的setAxe方法,將容器中的StoneAxe作為參數傳入 -->
        <property name="axe" ref="stoneAxe"/>
        <!-- 
        <property name="axe" ref="steelAxe"/>
         -->
    </bean>
    <!-- 配置StoneAxe實例,其實現類是StoneAxe -->
    <bean id="stoneAxe" class="test_2.StoneAxe"></bean>
    <bean id="steelAxe" class="test_2.SteelAxe"></bean>
</beans>
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanTest {
    public static void main(String[] args) {
        //創建Spring容器
        ApplicationContext ctx = new ClassPathXmlApplicationContext("test_2_bean.xml");
        //獲取chinese實例
        Chinese chinese = ctx.getBean("chinese",Chinese.class);
        //調用chinese的useAxe()方法
        chinese.useAxe();
    }
}

(3)使用Spring IoC的三個基本要點:

  1)應用程序的各組件面向接口編程;

  2)應用程序的各組件不再由程序主動創建,而是由Spring容器負責創建並初始化;

  3)Spring采用配置文件或註解來管理Bean的實現類、依賴關系,Spring容器根據配置文件或註解,利用反射來 創建實例,並為之註入依賴關系。

3.構造註入

(1)利用構造器來設置依賴關系的方式被稱為構造註入;

(2)本質:驅動Spring在底層以反射的方式執行帶指定參數的構造器,當執行帶參數的構造器時,就可以利用構造器參數對成員變量執行初始化;

(3)代碼

public interface Axe {
    public String chop();
}
public interface Person {
    public void useAxe();
}
public class Chinese implements Person{
    private Axe axe;
    //提供攜帶參數的構造器,參數是被依賴的Axe
    public Chinese(Axe axe){
        this.axe = axe;
    }
    @Override
    public void useAxe() {
        // TODO Auto-generated method stub
        System.out.println(axe.chop());
    }
}
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanTest {
    public static void main(String[] args) {
        //創建容器
        ApplicationContext ctx = new ClassPathXmlApplicationContext("test_3_bean.xml");
        //獲取對象
        Chinese c = ctx.getBean("chinese",Chinese.class);
        //調用方法
        c.useAxe();
    }
}    
<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-4.0.xsd"
    >
    <!-- 配置chinese實例,實現類是Chinese -->
    <bean id="chinese" class="test_3.Chinese">
        <constructor-arg ref="stoneAxe"/>
    </bean>
    <!-- 配置stoneAxe實例,實現類是StoneAxe -->
    <bean id="stoneAxe" class="test_3.StoneAxe"/>
</beans>

(4)配置<constructor-arg>元素,兩個屬性:

  1)index

  2)type

public class Student {
    private String name;
    private int age;
    private String sex;
    //構造器
    public Student(){
        
    }
    public Student(String name){
        this.name = name;
    }
    public Student(String name,int age){
        this(name);
        this.age = age;
    }
    public Student(String name,int age,String sex){
        this(name,age);
        this.sex = sex;
    }
    //Student方法
    public void sayHello(){
        System.out.println("我的名字是"+this.name+",今年"+this.age+"歲,是個"+this.sex+"同學");
    }
}
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class StudentTest {
    public static void main(String[] args) {
        //創建容器
        ApplicationContext ctx = new ClassPathXmlApplicationContext("test_3_bean.xml");
        //獲取對象
        Student st = ctx.getBean("student",Student.class);
        //執行方法
        st.sayHello();
    }
}    
<?xml version="1.0" encoding="UTF-8"?>
<!-- Spring配置文件的根元素,使用spring-beans-4.0.xsd語義約束 -->
<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-4.0.xsd"
    >
    <!-- 配置Student對象,其實現類是Student -->
    <!-- 構造註入 -->
    <bean id="student" class="test_3.Student">
        <constructor-arg value="小明" index="0"/>
        <constructor-arg value="25" index="1" type="int"/>
        <constructor-arg value="男" index="2"/>
        <!-- 
        <constructor-arg value="小明" />
        <constructor-arg value="25" />
        <constructor-arg value="男" />
         -->
    </bean>
</beans>

4.兩種註入方式的對比

  設值註入:通過無參構造器創建一個Bean,再使用setter方法註入依賴關系;

  構造註入:直接調用有參數的構造器,當Bean實例被創建完成後,已經完成了依賴關系的註入;

二、Spring的依賴註入