与@Alternative

时间:2015-10-23 11:24:57

标签: java cdi weld

我的一个课程中有一个注射点

@Inject
private UsbServices usbServices;

使用@Produces方法

的Weld类
public class AppProducer
{

    @Produces
    @Singleton
    public UsbServices getUsbServices()
    {
        UsbServices usbServices = null;
        try
        {
            usbServices = UsbHostManager.getUsbServices();
        } catch (SecurityException | UsbException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return usbServices;
    }

}

我希望在集成测试期间交换替代实现,因此我有上述类的替代版本

@Alternative
public class TestAppProducer
{

    @Produces
    @Singleton
    public UsbServices getUsbServices()
    {
        return new UsbServicesSimulator();
    }

}

以下是我的beans.xml里面的测试包resources / META-INF

<beans xmlns="http://java.sun.com/xml/ns/javaee" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
      http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
      <alternatives>
          <class>xxx.TestAppProducer</class>
      </alternatives>
</beans>

为了测试这个,我试图用它的主类启动Weld并手动连接USB'设备'。测试方法如下

Weld weld = new Weld();
WeldContainer container = weld.initialize();
PCSyncApplication app = container.instance().select(PCSyncApplication.class).get();
ServicesManager servMan = app.getServicesManager();
UsbServicesSimulator servSimulator = (UsbServicesSimulator) servMan.getUsbServices();
servSimualtor.attachDevice(new FakeDevice());

但是我得到了一个模棱两可的依赖异常

Exception in thread "main" org.jboss.weld.exceptions.DeploymentException: Exception List with 2 exceptions:
Exception 0 :
org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous dependencies for type UsbServices with qualifiers @Default
  at injection point [BackedAnnotatedField] @Inject private xxx.manager.ServicesManager.usbServices
  at xxx.manager.ServicesManager.usbServices(ServicesManager.java:0)
  Possible dependencies: 
  - Managed Bean [class xxx.simulator.usb.UsbServicesSimulator] with qualifiers [@Any @Default],
  - Producer Method [UsbServices] with qualifiers [@Any @Default] declared as [[BackedAnnotatedMethod] @Produces @Singleton public xxx.AppProducer.getUsbServices()]

编辑:如果我使用以下消息注释UsbServicesSimulator,则会发生小更新

@Alternative
public class UsbServicesSimulator implements UsbServices

但我不完全确定我理解为什么。我认为TestAppProducer的{​​{1}}和<alternatives>部分就足够了吗?

1 个答案:

答案 0 :(得分:1)

使用@Alternative注释,您只能禁用测试服务,但不能解决模糊的依赖关系。如果要启用Alternative,则主类型不应在类路径中可见,或者应具有较低的优先级e.x.使用beans.xml或@Vetoed注释或禁用@Priority。 还有一些其他技术,
您可以在https://docs.jboss.org/weld/reference/latest/en-US/html/injection.html#alternatives

找到完整的文档

我更喜欢使用单独的项目,或者使用Arquillian运行Test,并且只在类路径中使用该类,我需要的是什么。 在这种情况下,我不建议使用优先级。因为您需要为生产版本禁用或设置较低的优先级。