2017-04-07 2 views
0

Je suis au stade débutant de la CDI et essayer d'injecter la mise en œuvre de l'interface par injection de champ comme ci-dessous:Injection de contexte et de dépendance: comment injecter une implémentation d'une interface?

AutoService.java

package com.interfaces; 

public interface AutoService { 
    void getService(); 
} 

BMWAutoService.java

package com.implementations; 

import javax.inject.Named; 

import com.interfaces.AutoService; 

@Named("bmwAutoService") 
public class BMWAutoService implements AutoService { 

    public BMWAutoService() { 
     // TODO Auto-generated constructor stub 
    } 

    @Override 
    public void getService() { 
     System.out.println("You chose BMW auto service"); 

    } 

} 

AutoServiceCaller.java

package com.interfaces; 

public interface AutoServiceCaller { 
    void callAutoService(); 
} 

A utoServiceCallerImp.java

package com.implementations; 

import javax.inject.Inject; 
import javax.inject.Named; 

import com.interfaces.AutoService; 
import com.interfaces.AutoServiceCaller; 

public class AutoServiceCallerImp implements AutoServiceCaller { 

    @Inject 
    @Named("bmwAutoService") 
    private AutoService bmwAutoService; 

    public AutoServiceCallerImp() { 

    } 

    @Override 
    public void callAutoService() { 
     bmwAutoService.getService(); 

    } 

} 

TestDisplayMessage.java

package com.tests; 

import com.implementations.AutoServiceCallerImp; 
import com.interfaces.AutoServiceCaller; 

public class TestDisplayMessage { 

    public TestDisplayMessage() { 
     // TODO Auto-generated constructor stub 
    } 

    public static void main(String[] args) { 

     AutoServiceCaller caller = new AutoServiceCallerImp(); 

     caller.callAutoService(); 

    } 

} 

Quand je lance TestDisplayMessage.java, le résultat attendu serait "Vous avez choisi BMW service auto" mais je reçois NullPointerException comme ci-dessous:

Exception in thread "main" java.lang.NullPointerException 
    at com.implementations.AutoServiceCallerImp.callAutoService(AutoServiceCallerImp.java:21) 
    at com.tests.TestDisplayMessage.main(TestDisplayMessage.java:16) 

Impossible de comprendre exactement ce que je manque ici. S'il vous plaît aider.Merci à l'avance.

Répondre

0

Ok, il semble que vous ayez mal compris le concept de CDI - l'idée est de laisser le cycle de vie du bean au conteneur CDI. Cela signifie que CDI créera pour vous. En d'autres termes, vous êtes pas censé créer des haricots en appelant new. Si vous faites cela, CDI n'en sait rien et n'y injectera rien.

Si vous êtes dans l'environnement SE, ce que je pense que vous êtes puisque vous utilisez la méthode main pour tester, vous voulez utiliser Weld (mise en œuvre CDI) SE artefact (je suppose que vous faites cela). Là, vous devrez démarrer le conteneur CDI. Notez que si vous développiez une application EE classique sur un serveur, vous ne le faites pas, car le serveur le gérera pour vous. Maintenant, le moyen le plus basique de démarrer le conteneur Weld SE est:

Weld weld = new Weld(); 
try (WeldContainer container = weld.initialize()) { 
    // inside this try-with-resources block you have CDI container booted 
    //now, ask it to give you an instance of AutoServiceCallerImpl 
    AutoServiceCallerImpl as = container.select(AutoService.class).get(); 
    as.callAutoService(); 
} 

Maintenant, deuxième problème avec votre code. L'utilisation de @Named est destinée à la résolution EL. Par exemple. dans les pages JFS, de sorte que vous pouvez accéder directement au bean. Ce que vous voulez probablement est de différencier plusieurs implémentations AutoService et en choisir une donnée. Pour ce CDI a qualificateurs. Vérifiez this documentation section pour plus d'informations sur la façon de les utiliser.