Dependency injection 背景及;依赖注入:如何注入接口的实现?

Dependency injection 背景及;依赖注入:如何注入接口的实现?,dependency-injection,cdi,javax-inject,Dependency Injection,Cdi,Javax Inject,我处于CDI的初级阶段,尝试使用字段注入来注入接口的实现,如下所示: AutoService.java package com.interfaces; public interface AutoService { void getService(); } package com.implementations; import javax.inject.Named; import com.interfaces.AutoService; @Named("bmwAutoService

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

AutoService.java

package com.interfaces;

public interface AutoService {
    void getService();
}
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");

    }

}
BMWAutoService.java

package com.interfaces;

public interface AutoService {
    void getService();
}
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
时,预期结果将是“您选择了宝马汽车服务”,但我得到的NullPointerException如下所示:

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

我想不出我到底错过了什么。请帮助。提前感谢。

好的,您似乎有点误解了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,有限定符。查看有关如何使用它们的更多信息。

好的,您似乎有点误解了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,有限定符。查看有关如何使用它们的更多信息