web-dev-qa-db-ja.com

Springインターフェース注入の例

これまでのところ、Spring Frameworkでのインターフェイスインジェクションの実際の正しい例を提供できる人はいませんでした。マーティン・ファウラーの記事は定命のものではなく、他のすべては言葉を非常に混乱させて配置しています。私は、「Springはインターフェイスインジェクションを直接サポートしていない」(「セッターとコンストラクターのインジェクションのみを説明する方法が正確にわからないため」または「他のスレッド」またはそれが間違った例であるというコメントが下にいくつかあります。私は説明を求めません。たとえば、BEGです。

注入には、コンストラクター、セッター、インターフェースの3つのタイプがあります。 Springは最新のものを直接サポートしていません(私が言っているように)。では、正確にどのように行われますか?

ありがとうございました、

27
Aubergine

春のDIのバリエーション

DIは、コンストラクターベースの依存性注入とセッターベースの依存性注入の2つの主要なバリアントに存在します。

Springではインターフェイスインジェクションは実装されていません を参照してください。

したがって、DIには2つのバリアントしかありません。したがって、ドキュメントにインターフェイスインジェクションについて何も記載されていない場合は、そこにないことが明らかです。インターフェースにセッターメソッドを提供することでインターフェースインジェクションが行われると信じている人は私に答えます:

  1. なぜSpring ref docがインターフェイスインジェクションの言及を残したのですか?
  2. セッターメソッドを提供することでインジェクションをインターフェイスできないのはなぜですか[〜#〜] not [〜#〜]セッターインジェクション自体と見なされます。インターフェースの導入が何の影響も与えないのに、なぜ特別な用語を作成するのか、まだ同じように構成されているということです。それらが異なっていた場合、どのようにして構成を見ることでそれを見つけることができますか? configで、実際に設定されたクラスが何らかのインターフェースを実装するimplを表示しないのは透過的ではないでしょうか?
  3. インスタンスファクトリメソッドを使用したインスタンス化 および 静的ファクトリーメソッドを使用したインスタンス化 と同様に、一部のBean属性はインターフェイスインジェクションを明確にする必要がありますか?
12
nanosoft

インターフェイスインジェクションでは、インターフェイスは依存関係を設定できるポイントを明示的に定義します。

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

class Company implements InjectPerson {
   Person injectedPerson; 

   public void injectHere(Person p) {
        this.injectedPerson = p;
    }
}
8
Stefan

こんにちは私はあなたの答えを明確にするかもしれない非常に簡単なアプローチで試しました。

以下は、2つのインターフェイスと2つのBeanクラスを使用して構築したコードです。

jobという名前の最初のインターフェイス。

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

myJobという名前でこのインターフェイスを実装する1つのクラス

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

次に、メイン関数でメインクラスに作成し、次のようにコードを記述しました:

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>

また、別のオンラインチュートリアルを参照して、この種のソリューションを得ました。このコードに問題がある場合はお知らせください。それは私のために働いています。

6
Vinay Pandey

依存性注入には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つ)で混乱しているように見えます。

2
Goyal Vicky

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

}
1
Sivaranjani D

インターフェース注入に関する混乱は、「インターフェース注入」という用語の実際の意味を誤解しているためだと思います。私の理解では、インターフェイスインジェクションは、この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 contenerはこのBeanのインスタンスを独自に初期化するため、インターフェイスインジェクションではありません。言い換えると、card beanは初期化されたオブジェクトであり、インターフェースではなく、この質問に対して選択された答えが正しいことを示すものです。

1
Tinki

誰かがあなたの質問に答えたと思う ここ 「Webフローブックを備えたPro Spring MVC」からこのステートメントを読むまで、インターフェイスインジェクションが何であるかも知りませんでした

「インターフェースベースの依存性注入はSpring Frameworkではサポートされていないことに注意してください。これは、特定のインターフェースに注入する具体的な実装を指定する必要があることを意味します。」

1
Adelin