不同项目中的Bean接口和Bean实现

Bean interface and Bean implementation in different projects

是否可以在一个项目中有一个 bean 接口,并在另一个项目中实现该 bean,并将先前的项目作为依赖项包含在内?

我有以下界面:

package com.proj1.util;
import .....;

public interface Notification {

   addNotification();
   addError();    

}

在同一个项目(即 Proj1)中,我还有以下 class:

package com.proj1.util.exception;
import .....;

public class ExceptionHandler extends RuntimeException ... {
   private String errorMessage;

   @Override
   public void handle() {
      Util.getBeanInstance(Notification.class).addError(errorMessage);
   }    

}

现在在第二个项目中我有 Notification 的实际实现如下:

package com.proj2.beans;

@Named
@ConversationScoped
public class NotificationBean implements Notification, Serializable {
    private static final long serialVersionUID = 1L;

    ...
}

这种情况在 Tomcat 中导致异常,并显示消息“具有范围类型注释 @ConversationScoped 的 WebBeans 上下文在当前线程 中不存在”

我的建议是添加一个工厂来生成我的 NotificationBean,但它似乎没有太大变化。

package com.proj2.beans.cdi;

import javax.enterprise.inject.New;
import javax.enterprise.inject.Produces;

import com.proj1.util.Notification;

public class NotificationBeanFactory {

    @Produces
    public Notification create(@New NotificationBean notificationBean) {
        return notificationBean;
    }
}

问题是我如何在一个项目中使用一个 bean,在这个项目中我只有它的接口,而 bean 实现在另一个项目中。可能吗?

异常表明没有 运行 对话,所以我首先确定您何时尝试使用 @ConversationScoped bean 以及从哪个 class.

您的代码片段表明 ExceptionHandler class 调用了一个我们一无所知的神奇公式:

Util.getBeanInstance(Notification.class).add(...);

在没有活动对话时尝试使用它可能会导致您看到的异常。因此你可以 @Inject ExceptionHandler 变成 NotificationBean 这样你就可以只在有活跃对话时使用它。

关于不同项目中接口和实现的Weld问题;有可能的。在您的 proj2 中,Weld 将简单地识别一个 bean NotificationBean,并且在它的类型中也会有 Notification 因此您可以 @Inject Notification。 它可能无法反过来工作 - 在 proj1 中你不能 @Inject Notification 因为 proj1 本身没有任何可以实现该接口的 bean。