web-dev-qa-db-fra.com

Exemple d'injection d'interface Spring

Jusqu'à présent, personne n'était capable de fournir un exemple correct d'injection d'interface dans Spring Framework. L'article de Martin Fowler n'est pas destiné aux mortels, tout le reste n'est que des mots placés de manière très déroutante. J'ai surfé sur les articles TRENTE, où les gens disent soit "Spring ne supporte pas directement l'injection d'interface" ("et parce que je ne sais pas exactement comment je vais décrire les injections de setter et de constructeur"), "Autres discussions" ou soit il y aura quelques commentaires ci-dessous indiquant qu'il s'agit d'un mauvais exemple. Je ne demande pas d'explication, je commence par exemple.

Il existe trois types d'injection: Constructeur, Setter et Interface. Le printemps ne supporte pas les dernières nouveautés directement (comme j'ai pu l'observer dire). Alors, comment fait-on exactement?

Je vous remercie,

25
Aubergine

Selon Variantes de DI au printemps

DI existe en deux variantes principales, l’injection de dépendance par constructeur et l’injection de dépendance par Setter.

Voir également L'injection d'interface n'est pas implémentée dans Spring l'indique clairement.

Donc, il n'y a que deux variantes de DI. Donc, si la documentation ne dit rien sur l'injection d'interface, il est clair que ce n'est pas là. Ceux qui croient que l’injection d’interface se fait en fournissant une méthode de définition dans l’interface me répondent:

  1. Pourquoi Spring Ref Doc a-t-il parlé d'injection d'interface?
  2. Pourquoi l’injection d’interface via la méthode de définition ET NON n’est-elle pas considérée comme une injection de définition elle-même. Pourquoi créer un terme spécial pour cela lorsque l’introduction d’une interface n’affecte rien, je veux dire qu’elle est toujours configurée de la même manière. Si elles étaient différentes, comment peut-on le trouver en consultant la configuration? Ne devrait-il pas être transparent que dans config et ne pas voir l'impl que la classe réellement configurée implémente une interface?
  3. Tout comme Instanciation utilisant une méthode de fabrique d'instance et Instanciation utilisant une méthode de fabrique statique , certains attributs de bean devraient clarifier l'injection d'interface?
10
nanosoft

Avec l'injection d'interface, une interface définit explicitement le point où une dépendance peut être définie:

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

class Company implements InjectPerson {
   Person injectedPerson; 

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

Salut, j'ai essayé avec une approche très simple qui peut clarifier votre réponse.

voici le code que j'ai construit en utilisant deux interfaces et deux classes de haricots.

première interface nommée Job.

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

et une classe pour implémenter cette interface avec le nom 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;
    }
}

Dans l'étape suivante, j'ai créé une autre interface avec pour nom Service.

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

et encore une autre classe pour implémenter cette interface de service.

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

puis j'ai créé sur la classe principale avec la fonction principale et écrit le code comme suit:

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

dans mon fichier Beans.xml, j'ai mentionné le code comme suit et cela a fonctionné.

 <?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>

J'ai également consulté d'autres tutoriels en ligne et obtenu ce type de solution. s'il vous plaît laissez-moi savoir si vous avez un problème avec ce code. Ça marche pour moi.

6
Vinay Pandey

Il existe 3 types d'injections de dépendance: -

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 ne prend en charge que les injecteurs basés sur les constructeurs et les donneurs . On dirait que vous avez été confus entre les différents types (3) et ce que Spring prend en charge (2 d'entre eux).

2
Goyal Vicky

Veuillez vérifier l'exemple ci-dessous pour l'injection iterface.

Il existe une interface de forme et 2 classes concrètes qui imiplèment la forme, à savoir le carré et le rectangle.

L'interface

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

2 classes implémentées

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

}

Maintenant, nous avons une classe qui définit la forme.

public class ShapeSetter {

    private Shape shape;

    public Shape getShape() {
        return shape;
    }

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

}

et enfin la configuration

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

Ici,

nous injectons des formes différentes.

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

Je pense que la confusion autour de l’injection d’interface est due à une mauvaise compréhension de la signification réelle du terme "injection d’interface". D'après ma compréhension, l'injection d'interface décrit la capacité d'un contener de bean d'injecter une nouvelle interface au bean, peu importe si la définition de classe de ce bean ne l'implémente pas.

Tous les exemples présentés ici montrent comment créer un grain en classe concrète, puis comment l'injecter dans un autre grain. Le fait que, dans tous les cas, le bean soit injecté dans un champ défini comme une interface importe peu - toutes les opérations sont effectuées avec des beans créés à partir d'instances concrètes. 

Je peux aussi donner un autre exemple accrocheur:

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>

Comme vous le voyez ici, il est même possible de créer un haricot en dehors de l'interface! Néanmoins, il ne s’agit pas d’une injection d’interface, car IoC contener initialise lui-même l’installation de ce bean. En d'autres termes, le bean card est un objet initialisé et non une interface. Ce qui fait que la réponse sélectionnée pour cette question est correcte. 

1
Tinki

Je pense que quelqu'un a répondu à vos questions ici .__ Je ne savais pas non plus ce qu'est l'injection d'interface avant d'avoir lu cette déclaration de "Pro Spring MVC avec livret de flux Web" 

"Notez que l'injection de dépendance basée sur une interface n'est pas prise en charge par Spring Framework. Cela signifie Que nous devons spécifier quelle implémentation concrète injecter pour une certaine interface." 

1
Adelin