@EJB 注入与查找 - 性能问题
我有一个与使用 @EJB 注释时可能出现的性能问题相关的问题。想象一下以下场景:
public class MyBean1 implements MyBean1Remote{
@EJB
private MyBean2Remote myBean2;
@EJB
private MyBean2Remote myBean3;
...
@EJB
private MyBean20Remote myBean20;
}
有一个 bean 对其他 bean 有许多依赖项。根据 EJB 规范,如果我想将 MyBean1Remote 注入到其他某个 bean,容器必须从其池中获取所有必需的依赖项,将其注入到 MyBean1Remote 中,然后注入对 MyBean1Remote 存根的引用。
因此,在以下场景中,容器需要保留 20 个 ejb(myBean1 及其 19 个依赖项)。
public class MyAnotherBean implement MyAnotherRemote{
@EJB
private MyBean1Remote myBean1
}
假设在大多数情况下,我们将仅对 myBean1 的每个业务方法使用单个依赖项。因此,每次我们想要注入该 bean 时,我们都会强制容器保留许多不必要的 EJB。我们还假设我们正在远程 bean 上进行操作,因此容器可能还需要在注入依赖 bean 之前执行一些负载平衡算法。
问题:
在集群环境中运行时,这是否会导致不必要的资源预留和更多的性能问题?
也许旧的 ServiceLocator 可能是更好的解决方案,因为使用这种方法,我们会在真正需要时请求特定的 EJB?
I have a question related with possible performance issue while using @EJB annotation. Imagine following scenario
public class MyBean1 implements MyBean1Remote{
@EJB
private MyBean2Remote myBean2;
@EJB
private MyBean2Remote myBean3;
...
@EJB
private MyBean20Remote myBean20;
}
There is a bean with many dependencies to other beans. According to EJB spec if I would like to inject MyBean1Remote to some other bean, container would have to take all required dependencies from its pool inject it into MyBean1Remote and then inject reference to MyBean1Remote stub.
so in following scenario container needs to reserved 20 ejbs (myBean1 and its 19 dependencies)
public class MyAnotherBean implement MyAnotherRemote{
@EJB
private MyBean1Remote myBean1
}
Let say that in most cases we will use only single dependency per each business method of myBean1. As a result each time we want to inject that bean we force container to reserves many unnecessery EJBs. Lets also assume that we are operating on remote beans so probably container would also need to perform some load balancing algorithm prior injecting dependent beans.
Questions:
Wouldn't that cause unnecessary resource reservation and more over performance issue while operating in cluster environment?
Maybe good old ServiceLocator could be better solution because with this approach we would ask for specific EJB when we really need it ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
容器不会注入 EJB 实例;它注入一个轻量级容器生成的代理对象的实例,该对象实现所需的接口。
在您的示例中,MyAnotherBean.myBean1 将注入一个实现 MyBean1Remote 接口的代理对象。
假设是一个无状态会话 bean(因为您提到了池),容器不会从方法就绪池中分配实际的 EJB 实例,直到在代理上调用方法,并且该实例返回到代理方法调用返回之前的池。
The container does not inject an instance of the EJB; it injects an instance of a lightweight container-generated proxy object that implements the desired interface.
In your example, MyAnotherBean.myBean1 will be injected with a proxy object that implements the MyBean1Remote interface.
Assuming a stateless session bean (since you mention pooling), the container does not allocate an actual EJB instance from the method-ready pool until a method is called on the proxy, and the instance is returned to the pool before the proxy method call returns.
在大多数情况下,尤其是在使用无状态会话 bean 时,您的 bean 实例将被池化。池化背后的基本原理之一是依赖项注入查找可能相对昂贵,因此 bean 与已注入的所有依赖项(存根)一起池化。
因此,每次您调用
MyAnotherBean
上的方法时,这个具有 20 个传递依赖项的 Bean 并不是在创建时动态解析所有这些依赖项的。相反,从池中选择一个完全实例化的实例,并将方法调用定向到该实例。另请注意,除非您正在进行 JNDI 联合,否则通常无法轻松注入远程 EJB。
In most cases and especially when using stateless session beans, your bean instances will be pooled. One of the rationales behind pooling is that dependency injection lookups might be relatively expensive, so the bean is pooled with (stubs for) all its dependencies already injected.
So every time you call a method on
MyAnotherBean
, This bean with its 20 transitive dependencies isn't created with all those dependencies resolved on the fly. Instead, a fully instantiated instance is selected from the pool and the method call is directed to that.Also note that unless you are doing JNDI federation you normally can't easily inject remote EJBs.