2012-04-20 118 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是一个初始化的对象,而不是一个接口,是什么使得这个问题的选择答案是正确的。