Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java @注入、@EJB、@Local、@Remote、@LocalBean等…:困惑的_Java_Jakarta Ee_Ejb_Cdi - Fatal编程技术网

Java @注入、@EJB、@Local、@Remote、@LocalBean等…:困惑的

Java @注入、@EJB、@Local、@Remote、@LocalBean等…:困惑的,java,jakarta-ee,ejb,cdi,Java,Jakarta Ee,Ejb,Cdi,我有以下配置: 一个GF上有1个EAR,包含2个带有EJB组件的EJB JAR 1在另一个Glassfish服务器(=>其他JVM)上运行WAR,该服务器包含访问EJB组件的web组件 我EAR的每个EJB-JAR中有2个EJB业务服务,它们都是这样开发的: @Remote public interface ServiceAItf { ... } @Stateless @Local public class ServiceAImpl implements ServiceAItf {

我有以下配置:

  • 一个GF上有1个EAR,包含2个带有EJB组件的EJB JAR
  • 1在另一个Glassfish服务器(=>其他JVM)上运行WAR,该服务器包含访问EJB组件的web组件
我EAR的每个EJB-JAR中有2个EJB业务服务,它们都是这样开发的:

@Remote
public interface ServiceAItf {
    ...
}

@Stateless
@Local
public class ServiceAImpl implements ServiceAItf {
    ...
}
@Stateless
@Local
public class ServiceBImpl implements ServiceBItf {
    @Inject
    private ServiceAItf serviceA;
    ...
}
在WAR中,我通过远程接口上的显式“InitialContext.lookup”访问EJB组件

在我看来,我对注射的最佳实践非常困惑,在性能、架构等方面

我有以下问题:

  • 如您所见,我在服务实现上声明了注释“@Local”,而没有定义本地接口。对吗?至少我在部署时没有错误。但也许我应该用“@LocalBean”注释来代替?我假设“@LocalBean”注释只允许将实现作为“本地”EJB直接调用,但您必须在代码中使用实现,如下所示:

    @Remote
    public interface ServiceAItf {
        ...
    }
    
    @Stateless
    @Local
    public class ServiceAImpl implements ServiceAItf {
        ...
    }
    
    @Stateless
    @Local
    public class ServiceBImpl implements ServiceBItf {
        @Inject
        private ServiceAItf serviceA;
        ...
    }
    
    @无国籍 @本地的 公共类ServiceBImpl实现ServiceBItf{ @EJB 私人服务aimpl服务a; ... }

  • 将一个EJB注入另一个EJB的最佳方式是什么? 它的工作原理如下:

    @Remote
    public interface ServiceAItf {
        ...
    }
    
    @Stateless
    @Local
    public class ServiceAImpl implements ServiceAItf {
        ...
    }
    
    @Stateless
    @Local
    public class ServiceBImpl implements ServiceBItf {
        @Inject
        private ServiceAItf serviceA;
        ...
    }
    
    @无国籍 @本地的 公共类ServiceBImpl实现ServiceBItf{ @EJB 私人服务aitf serviceA; ... }

但我注意到,注入的“serviceA”是远程代理,而它位于同一个EAR文件中的同一个JVM中。因此,我认为这将对性能产生影响。这就是为什么我尝试像这样注入服务:

@Remote
public interface ServiceAItf {
    ...
}

@Stateless
@Local
public class ServiceAImpl implements ServiceAItf {
    ...
}
@Stateless
@Local
public class ServiceBImpl implements ServiceBItf {
    @Inject
    private ServiceAItf serviceA;
    ...
}
但它在GF中不起作用,我有以下例外:

WELD-001408 Unsatisfied dependencies for type [...] ...
然后,我尝试创建一个本地接口,当两个服务都提供时,通过注释“@Inject”的注入可以工作

即使我创建了这样的本地接口,服务也不会通过注释“@Inject”注入,而是为null:

@Local
public interface ServiceALocalItf {
    ...
}
我读过很多文章,其中强烈建议在本地调用时使用“@Inject”而不是“@EJB”。这就引出了下面的问题:在哪种情况下,建议使用“@Local”EJB调用(或简单地使用)

经过所有这些分析,我得出以下结论:

  • 对于每个服务,我创建一个“@Local”和一个“@Remote”接口
  • 从WAR到EAR的EJB-JAR,对远程接口进行JNDI查找
  • 从EJB-JAR到EJB-JAR,通过“@EJB”注入本地接口
  • 对于同一EJB-JAR中的两个服务,通过“@Inject”向本地接口进行注入

你觉得怎么样?是否正确?

@Inject
注释用于java bean(POJO),而
@EJB
注释用于企业java bean。当容器将
@ejb
注释提供的ejb注入到另一个bean时,它还控制该ejb的生命周期,为无状态bean执行池等等(当要注入的bean未部署时,引用将为null)。如果您使用
@Inject
注释CDI机制,只需查找并创建一个注入资源的实例,如new operator(如果要注入的接口的实现不存在,则引用将为null)。您可以使用带有
@Inject
注释的限定符来选择注入接口的不同实现

如您所见,我已经在服务上声明了注释“@Local” 不定义本地接口的实现。对吗

在EJB3.1中,对本地接口的要求被放弃了。除非您明确需要,否则无需编写它们

将一个EJB注入另一个EJB的最佳方式是什么

在这里写几件事:

有了JavaEE6,Java企业发生了变化。一个新的JSR将所谓的托管bean(不要与JSF托管bean混淆)定义为一种最小组件,它仍然可以从容器中获得依赖注入和生命周期管理方面的好处。这意味着:如果您有一个组件,并且“只是”想要使用DI并让容器控制其生命周期,那么您不需要为它使用EJB。如果(并且仅当)您明确需要EJB功能,如事务处理、池、钝化和集群,您将最终使用EJB

这使得您的问题的答案分为三个部分:

  • 使用@Inject over@EJB,CDI(a)的概念适用于所有托管服务器 bean(这包括EJB)和(b)是有状态的,因此到目前为止 优于纯@EJB DI
  • 您确定您的应用程序需要EJB吗 组件
  • 这绝对值得一看CDI

  • 如果@Inject用于POJO,则它们必须通过引用传递参数,而不像EJB那样通过值传递参数。我说的对吗?你说的是什么参数?>@Inject注释用于Javabean(POJO)。不完全正确。它也用于EJB和CDIBeans注入。maks-很抱歉,您的措辞是误导性的,如果不是错误的话@Inject在POJO上不起作用,它在ManagedBeans(JSR316)上起作用,并控制生命周期。ManagedBeans的实例化与调用新操作符完全不同-您缺少CDI的整个上下文部分(每个ManagedBean驻留在一个上下文中,因此其生命周期绑定到上下文的生命周期)…首先,感谢您的回答;-)对于注释“@Local”,我的问题更多的是没有定义接口的注释“@Local”和注释“@LocalBean”之间的行为差异?结果是一样的:一个没有接口的本地bean,不是吗??在我们的例子中,我们确实需要ejbremote从前端(在一台服务器上)到后端(在另一台服务器上)进行通信。“CDI是状态完整的”是什么意思?关于生命周期人