【问题标题】:Context & Dependency Injection : How to inject implementation of an interface?上下文和依赖注入:如何注入接口的实现?
【发布时间】:2017-04-07 01:16:29
【问题描述】:

我处于 CDI 的初学者阶段,并尝试使用字段注入来注入接口的实现,如下所示:

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

AutoServiceCallerImp.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();

    }

}  

当我运行 TestDisplayMessage.java 时,预期的结果将是“您选择了 BMW 汽车服务”,但我得到如下 NullPointerException :

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

无法弄清楚我在这里缺少什么。请帮忙。提前致谢。

【问题讨论】:

    标签: dependency-injection cdi javax-inject


    【解决方案1】:

    好的,您似乎有点误解了 CDI 的概念 - 想法是将 bean 生命周期留给 CDI 容器。这意味着 CDI 将为您创建一个处置 bean。换句话说,您应该通过调用new 来创建bean。如果你这样做,CDI 不会知道它,也不会向它注入任何东西。

    如果你在 SE 环境中,我认为你是因为你使用 main 方法进行测试,你想使用 Weld(CDI 实现)SE 工件(我猜你这样做)。 在那里,您需要启动 CDI 容器。请注意,如果您在服务器上开发经典的 EE 应用程序,则不要这样做,因为服务器会为您处理它。现在,启动 Weld SE 容器的最基本方法是:

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

    现在,您的代码的第二个问题。 @Named 的使用旨在用于 EL 分辨率。例如。在 JFS 页面中,因此您可以直接访问 bean。 您可能想要的是区分几个AutoService 实现并选择一个给定的实现。因为 CDI 有限定符。请查看this documentation section 了解有关如何使用它们的更多信息。

    【讨论】:

      猜你喜欢
      • 2015-10-18
      • 1970-01-01
      • 1970-01-01
      • 2020-10-09
      • 1970-01-01
      • 2012-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多