2012-04-20 115 views
20

到目前爲止,還沒有人能夠在Spring Framework中提供正確的接口注入示例。馬丁福勒的文章不是爲了凡人,其他的一切只是以非常混亂的方式定位。我瀏覽了超過三十篇文章,其中人們要麼告訴「Spring不直接支持接口注入」(「因爲我不知道我將如何描述二進制和構造函數注入」或者「我會在我的討論中其他線程「,或者下面會有幾條評論說它是錯誤的例子。我不要求解釋,我舉例說。Spring接口注入示例

有三種類型的注入:構造函數,設置器和接口。 Spring不直接支持最新版本(正如我觀察到的人們所說的)。那麼它是如何完成的?

謝謝你,

+0

你知道,除了「不知道這個話題」之外,可能會因爲其他原因而降低投票率。什麼,*特別*,你想要一個例子嗎?爲你的問題定義「接口注入」。 – 2012-04-20 14:22:55

+1

我猜downvote是迴應你的第一段咆哮和事實,你的實際問題是模糊的,可以很容易地簡化爲「有人可以給和Spring接口注入的例子嗎?我已經搜索了幾個網站,還沒有找一個。」 (當然,這是你的問題)如果你發佈了你閱讀過的文章,那麼人們可以更好地瞭解你已經看過的內容。 – lrAndroid 2012-04-20 14:27:11

+1

除了來自@NimChimpsky(在Spring中稱爲AutoWiring並且通過Annotations或XML支持)的答案外,還有一個關於這個主題的大量資源的SO問題:http://stackoverflow.com/questions/2827147/真的支持接口注入在所有 – 2012-04-20 14:30:01

回答

7

根據Variants of DI in spring

DI主要有兩種變型,基於構造函數的依賴注入和基於setter方法的依賴注入。

另見Interface injection is not implemented in Spring明確指出它。

所以如果說文檔中沒有提到接口注入,那麼就清楚它不存在。那些認爲接口注入是通過提供在接口ING setter方法回答我:

  1. 爲什麼春天裁判DOC左接口注入的提?
  2. 爲什麼不能通過提供setter方法接口注入不是認爲是setter注入本身。爲什麼在引入接口不會影響任何內容時爲此創建特殊術語,我的意思是它仍然以相同的方式配置。如果它們不同,那麼通過查看配置如何找到它。它不應該是透明的,在配置和沒有看到實際配置的類實現一些接口的impl?
  3. 就像Instantiation using an instance factory methodInstantiation using an static factory method,一些bean屬性應該闡明接口注入?
+1

我自己花了相當長的時間解決了這個問題後,我相信nanosoft花費了足夠的努力來反駁其他答案。至少沒有任何證據或例子不會在Spring IoC中使用接口和接口注入混淆setter/constructor DI。再次做好研究和洞察。 – Aubergine 2015-07-19 12:10:37

7

隨着接口注入接口明確定義了依賴可設置點:

interface InjectPerson { 
    public void injectHere(Person p); 
} 

class Company implements InjectPerson { 
    Person injectedPerson; 

    public void injectHere(Person p) { 
     this.injectedPerson = p; 
    } 
} 
+2

不,注射是在別處完成的。這只是說「一個公司應該能夠注入一個人」。 – Stefan 2012-04-20 14:58:25

+0

查看我的答案 - http://stackoverflow.com/a/31244931/1406510 – nanosoft 2015-07-06 11:43:08

+0

這是圍繞不接口注入 - http://www.springbyexample.org/examples/core-concepts-dependency-injection-to-the- rescue.html – nanosoft 2015-07-06 14:09:02

6

您好我試圖用一個非常簡單的方法可闡明你的答案。

以下是我使用兩個接口和兩個bean類構建的代碼。

名稱爲Job的第一個界面。

public interface Job { 
    public void setmyJob(String myJob); 
    public String getmyJob(); 
} 

和一個類,以便實現具有名稱這個接口爲MyJob

public class MyJob implements Job { 
    public String myJob; 

    public MyJob() { 
     System.out.println("From MyJob default Constructor and the ID= "+this); 
    } 

    public void setmyJob(String myJob) { 
     this.myJob=myJob; 
    } 

    public String getmyJob() { 
     return myJob; 
    } 
} 

在我創建另一個接口,具有名稱作爲服務

public interface Service { 
    public void setJob(Job job); 
    public Job getJob(); 
} 

下一步驟,然後再另一個類實現這個服務接口。

public class MyService implements Service { 

    public Job job; 

    public void setJob(Job job) { 
     this.job=job; 
     System.out.println("Hello from Myservice: Job ID="+job); 
    } 

    public Job getJob() { 
     return job; 
    } 
} 

然後我在主類創建了主要功能和編寫的代碼如下:

import org.springframework.beans.factory.BeanFactory; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.support.ClassPathXmlApplicationContext; 
public class MainApplication { 

    public static void main(String...a) { 

     BeanFactory beanfactory=new ClassPathXmlApplicationContext("Beans.xml"); 

     MyService myservice=(MyService)beanfactory.getBean("myservice"); 
     System.out.println("Before print"); 
     System.out.println(myservice.getJob().getmyJob()); 
    } 
} 

在我的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-3.0.xsd"> 


    <bean id="myjob" class="MyJob"> 
     <property name="myJob" value="My First String"/> 
    </bean> 

    <bean id="myservice" class="MyService"> 
     <property name="job" ref="myjob"/> 
    </bean> 
</beans> 

我也接受了另一個在線教程,然後得到了這樣的解決方案。如果您對此代碼有任何問題,請告訴我。它爲我工作。

+0

你能告訴我你在哪裏的在線教程? – sunleo 2014-09-22 17:38:28

+0

那麼是什麼使它與二傳手注射不同?你有MyService類中的屬性工作,你基本上通過setter方法注入,因此setter注入...只是介紹接口沒有任何區別,我相信.... – nanosoft 2015-07-05 05:49:54

+0

請參閱我的回答 - http:// stackoverflow。 com/a/31244931/1406510 – nanosoft 2015-07-06 11:43:00

1

我覺得有人回答您的問題here 我也不知道接口注入是什麼,直到我讀從這句話中「臨春MVC與網絡流量的書」

「需要注意的是基於接口的依賴注入ISN不支持Spring框架,這個 意味着我們需要指定爲某個接口注入哪個具體實現。「

1

有3種類型的依賴注射: -

1. Constructor Injection(E.g Pico Container, Spring supports it). 
2. Setter Injection(E.g Spring supports it). 
3. Interface Injection(E.g Avalon, Spring does not support it). 

Spring支持唯一的構造和setter基於注射。 看起來你對不同類型(3)和彈簧支持(其中2個)有困惑。

1

請檢查以下示例iterface注射。

有形狀界面和實現形狀的2個具體類即正方形和長方形。

接口

package di.interfaceinjection; 
public interface Shape { 
    public String shapeName(); 
    public void displayName(); 
} 

2實現的類

package di.interfaceinjection; 

public class Square implements Shape { 

    @Override 
    public String shapeName() { 
     return "Square"; 
    } 

    @Override 
    public void displayName() { 
     System.out.println("Square");  
    } 

} 

package di.interfaceinjection; 

public class Rectangle implements Shape{ 

    @Override 
    public String shapeName() { 
     return "Rectangle"; 
    } 

    @Override 
    public void displayName() { 
     System.out.println("Rectangle");   
    } 

} 

現在,我們有一個類其設定的形狀。

public class ShapeSetter { 

    private Shape shape; 

    public Shape getShape() { 
     return shape; 
    } 

    public void setShape(Shape shape) { 
     this.shape = shape; 
    } 

} 

,最後配置

<bean id="shape1" class="di.interfaceinjection.ShapeSetter"> 
    <property name="shape" ref="square"></property> 
    </bean> 
    <bean id="shape2" class="di.interfaceinjection.ShapeSetter"> 
    <property name="shape" ref="rectangle"></property> 
    </bean> 
    <bean id="square" class="di.interfaceinjection.Square"></bean> 
    <bean id="rectangle" class="di.interfaceinjection.Rectangle"></bean> 

這裏,

我們注入不同的形狀。

package di.interfaceinjection; 

import org.springframework.context.ApplicationContext; 
import org.springframework.context.support.ClassPathXmlApplicationContext; 

public class InterfaceInjeection { 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     ApplicationContext appContext = new ClassPathXmlApplicationContext("intro.xml"); 
     ShapeSetter shape = (ShapeSetter)appContext.getBean("shape2"); 
     shape.getShape().displayName(); 
    } 

} 
0

我認爲界面注入造成的困惑是由於誤解術語「接口注入」實際上意味着造成的。在我的理解中,接口注入描述了一個bean競爭者向bean注入一個新接口的能力,不管這個bean的類定義是否沒有實現它。

此處介紹的所有示例都顯示瞭如何從具體類創建一個bean,然後如何將它注入到另一個bean中。事實上,在任何情況下,bean都被注入到一個定義爲接口的域中並不重要,所有的操作都是使用具體實例創建的bean來完成的。

我還可以提供另一種吸引人的例子:

package creditCards; 

interface PaymentCard { 
    Boolean isDebitAllowed(); 
} 

    <bean id="card" class="creditCards.PaymentCard"> 
     <lookup-method name="isDebitAllowed" bean="boolValue"/> 
    </bean> 

    <bean id="boolValue" class="java.lang.Boolean"> 
     <constructor-arg type="boolean" value="true"/> 
    </bean> 

正如你在這裏看到的,它甚至有可能出接口創建一個bean!儘管如此,它並不是一個接口注入,因爲IoC競爭者自己初始化了這個bean的實例。換句話說,card bean是一個初始化的對象,而不是一個接口,是什麼使得這個問題的選擇答案是正確的。