38

到目前为止,没有人能够在 Spring Framework 中提供一个正确的接口注入示例。

Martin Fowler 的文章不适合凡人,其他一切都只是以非常混乱的方式定位的文字。我浏览了 30 篇文章,人们要么告诉“Spring 不直接支持接口注入”(“而且因为我不知道我将如何仅描述 setter 和构造函数注入”)或者“我将讨论它”在我的其他线程中”或者下面很少有评论说这是错误的例子。我不要求解释,例如我BEG。

注入分为三种类型:构造函数、设置器和接口。Spring 不直接支持最新的(正如我观察到人们所说的那样)。那么具体是怎么做的呢?

谢谢你,

4

7 回答 7

16

根据春季DI的变体

DI 存在两种主要的变体,基于构造函数的依赖注入和基于 Setter 的依赖注入。

另请参阅接口注入未在 Spring 中实现明确说明。

所以DI只有两种变体。因此,如果文档没有说明接口注入,很明显它不存在。那些认为接口注入是通过在接口中提供setter方法来完成的人回答我:

  1. 为什么 spring ref doc 提到了接口注入?
  2. 为什么不能通过提供被视为 setter 注入本身的 setter 方法来接口注入。为什么要在引入接口不影响任何东西时为此创建特殊术语,我的意思是它仍然以相同的方式配置。如果它们不同,那么如何通过查看配置找到它。在配置中并没有看到实际配置的类实现某个接口的 impl 不应该是透明的吗?
  3. 就像使用实例工厂方法的实例化和使用静态工厂方法的实例化一样,一些bean属性应该澄清接口注入?
于 2015-07-06T11:41:09.910 回答
10

通过接口注入,接口显式定义了可以设置依赖项的点:

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

class Company implements InjectPerson {
   Person injectedPerson; 

   public void injectHere(Person p) {
        this.injectedPerson = p;
    }
}
于 2012-04-20T14:37:08.343 回答
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;
    }
}

在下一步中,我创建了另一个名为 Service 的接口

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;
    }
}

然后我用 main 函数在主类上创建并编写代码如下:

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>

我也参考了另一个在线教程,然后得到了这种解决方案。如果您对此代码有任何问题,请告诉我。它对我有用。

于 2013-02-04T10:14:32.407 回答
4

依赖注入有 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 仅支持基于构造函数和设置器的注入。看起来你对不同的类型(3)和弹簧支持的东西(其中 2 个)感到困惑。

于 2015-08-11T11:46:42.217 回答
3

我认为,围绕接口注入的混淆是由于误解了“接口注入”一词的实际含义。在我的理解中,接口注入描述了 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 的实例。换句话说,cardbean 是一个初始化的对象,而不是一个接口,这使得这个问题的选择答案是正确的。

于 2016-04-23T11:19:49.713 回答
1

我想有人在这里回答了你的问题 我也不知道接口注入是什么,直到我从“Pro Spring MVC with web flow book”中阅读了这个声明

“请注意,Spring 框架不支持基于接口的依赖注入。这意味着我们需要指定为某个接口注入哪个具体实现。”

于 2014-08-28T13:29:47.397 回答
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();
    }

}
于 2015-11-15T06:17:57.393 回答