Dependency injection 背景及;依赖注入:如何注入接口的实现?
我处于CDI的初级阶段,尝试使用字段注入来注入接口的实现,如下所示: AutoService.javaDependency 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
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,有限定符。查看有关如何使用它们的更多信息