1. 程式人生 > 其它 >spring 依賴注入_Spring核心機制:依賴注入

spring 依賴注入_Spring核心機制:依賴注入

技術標籤:spring 依賴注入spring依賴注入spring依賴注入的三種方式spring呼叫mybatis的dao時是怎樣的

4ea11369642e52e1d555e085e3b08f52.png

何為依賴關係?

縱觀所有Java應用,這些應用中大量存在A物件需要呼叫B物件方法的情形,這些情形被Spring稱為依賴,即A物件依賴B物件,這些相互呼叫的關係稱為依賴關係。

1. 傳統模式下的依賴

當某個Java物件(呼叫者)需要呼叫另一個Java物件(被依賴物件)的方法時,在傳統模式下通常有兩種方法:

1.原始做法:呼叫者主動建立被依賴的物件,然後呼叫被依賴物件的方法。

   class Skill {       public void run() {           System.out.println("我有跑步的能力");       }   }   class Person {       private Skill skill;       // 直接在構造器內new一個Skill物件       public Person() { this.skill = new Skill() }       public void setSkill(Skill skill) {           this.skill = skill;       }       public void doSports() {           skill.run(); //呼叫skill物件的run方法       }   }

1.簡單工廠模式:呼叫者先找到被依賴物件的工廠,然後主動通過工廠去獲取被依賴的物件,最後呼叫被依賴物件的方法。

   // 定義PersonSkill介面   public interface PersonSkill {       void run();   }
   class Skill implement PersonSkill {       public void run() {           System.out.println("我有跑步的能力");       }   }   // 增加一個工廠類,負責Skill物件的例項化   class PersonSkillFactory {       public static PersonSkill getSkill() {           return new Skill();       }   }   class Person {       private Skill skill;       // 呼叫工廠獲得Skill物件       public Person() { this.skill = PersonSkillFactory.getSkill() }       public void doSports() {           skill.run(); //呼叫skill物件的run方法       }   }

2. Spring核心:依賴注入

對於原始方法,呼叫者通過顯式的new 被依賴物件建立物件,這將導致呼叫者與被依賴物件的硬編碼耦合。

簡單工廠模式雖然保證了呼叫者與被依賴物件介面的耦合,但仍需要主動通過工廠去獲取被依賴物件,造成呼叫元件與被依賴物件工廠的耦合,並且需要額外的維護一個工廠類,增加了編碼的複雜性。

以上兩種方式都不能很好的實現程式碼的解耦


Spring框架的核心功能有兩個:

•Spring容器作為超級大工廠,負責建立、管理所有的Java物件,這些Java物件被稱為Bean。•Spring管理著Bean之間的依賴關係,這是使用一種稱為“依賴注入”的方式實現的。

Spring引入了xml

配置檔案來管理容器中的Bean。為了闡述依賴注入的具體含義,針對上面原始做法的示例,我們將PersonSkill進行些許改造:

class Skill {    public void run() {        System.out.println("我有跑步的能力");    }}class Person {    private Skill skill;    private Integer age;    //為skill屬性新增setter方法    public void setSkill(Skill skill) {        this.skill = skill;    }    //為age屬性新增setter方法    public void setAge(Integer age) {        this.age = age;    }    public void doSports() {        skill.run(); //呼叫skill物件的run方法    }}

Resource目錄下建立spring-beans.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">        <bean id="person" class="com.codeqis.beans.Person">                <property name="skill" ref="skill"/>          <property name="age" value="18"/>    bean>    <bean id="skill" class="com.codeqis.beans.Skill"/>beans>

完成這些步驟後,意味著將SkillPerson這兩個物件的建立權(控制權)交給了Spring,可以理解為將物件的控制權從使用者手中轉移給了由容器控制,這便是控制反轉

既然已經把Person的建立交由Spring管理了,那麼我們不應該再手動的new Person()

public class App {publicstaticvoidmain(String[]args){ApplicationContextcontext=new ClassPathXmlApplicationContext("spring-beans.xml");        // 方式1Personperson=(Person)context.getBean("person");//傳入beanid        // 方式2        Person person2 = context.getBean("person", Person.class);        person.doSports();        person1.doSports();    }}

在建立ClassPathXmlApplicationContext物件時,Spring將在ClassPath下面尋找spring-beans.xml,並根據該檔案來建立Spring容器,在此過程中Spring完成所有bean的例項化,併為所有bean注入被依賴的其他bean。

換言之,我們在spring-beans.xml中聲明瞭id為personskill的兩個bean,Spring容器在建立時自動例項化這兩個類的物件(預設是以單例模式存在),因為在id為person的bean下面還存在著子元素,容器在該物件例項化完成後隨即的呼叫該物件的setSkillsetAge方法(由name指定)完成被依賴物件(由ref指定)的注入。


正如前面的程式碼中所看到,程式程式碼並沒有主動為Person物件的skill成員變數設定值,而是由Spring容器負責設定,這便是依賴注入。Java EE應用中的各種元件不需要以硬編碼的方式耦合在一起,甚至無需使用工廠模式。個人認為依賴注入達到的效果,非常類似於傳說中的共產主義,當某個Java例項需要其他Java例項時,系統自動提供所需要的例項,無需顯式獲取。