找出使用什么EJB视图
问题描述:
假设我定义两种观点的EJB:找出使用什么EJB视图
- 本地业务,
- 远程业务。
两个接口都共享相同的方法签名,所以它是这样的:
public interface MyBusinessCommon {
void myMethod(Object o);
}
@Local
public interface MyBusinessLocal extends MyBusinessCommon { }
@Remote
public interface MyBusinessRemote extends MyBusinessCommon { }
@Stateless
public class MyBusinessBean implements MyBusinessLocal, MyBusinessRemote {
public void myMethod(Object o) {
// ...
}
}
有没有办法找出EJB视图是从EJB本身内调用(或它的拦截器?)
假设我想根据使用的视图执行不同的授权过程。远程应该更受约束,本地不应该。
我可以调用SessionContext#getInvokedBusinessInterface()
但这只给我提供关于类对象的信息 - 而不是关于它的EJB语义。显然使用反射来检查界面或bean上的注释存在是不够的(ejb-jar.xml
中定义的视图怎么办?)
我怀疑是否可以使用直接的EJB规范,但也许有一些我错过了。
如果没有,是否可以从应用程序服务器的内部获取此信息? (我们只考虑JBoss AS 7.x,Glassfish 3.x和TomEE 1.5.1)。
答
就像Arjan说的那样 - 仅仅遵循EJB规范是不可能的。
但是,在Glassfish中做起来相当简单。
所有EJB拦截器都接受参数InvocationContext
。实际上Glassfish中的InvocationContext
实际上是com.sun.ejb.EjbInvocation
类。它有isLocal
字段,告诉你它是否拦截本地业务呼叫(或用于远程业务呼叫的isRemote
)。 您可以使用它,例如如下:
import com.sun.ejb.EjbInvocation;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
@Interceptor
public class CallSourceAwareInterceptor {
@AroundInvoke
public Object aroundInvoke(InvocationContext ictx) throws Exception {
boolean isLocalCall = isLocalEJBCall(ictx);
return ictx.proceed();
}
boolean isLocalEJBCall(final InvocationContext ictx) {
if (ictx instanceof EjbInvocation) {
return ((EjbInvocation) ictx).isLocal;
}
else {
throw new IllegalArgumentException("Unknown InvocationContext implementation.");
}
}
}
要访问此EjbInvocation
内部Glassfish的类,你需要添加以下Maven的依赖:
<dependency>
<groupId>org.glassfish.main.ejb</groupId>
<artifactId>ejb-container</artifactId>
<version>4.0.1-b02</version>
<scope>provided</scope>
</dependency>
,你可能需要添加下列特定仓库去这个神器访问:
<repositories>
<repository>
<id>maven-promoted</id>
<url>https://maven.java.net/content/groups/promoted/</url>
</repository>
</repositories>
我做了一个快速的研究(基于理查德关于Invocation
对象的建议)如何在JBoss中实现相同但不能d回答...
我的直觉告诉我们,这不可能以便携的方式进行。如果是这样,我也错过了一些东西。一个窍门可能是使用命名接口的约定。你已经这样做了; 'MyBusinessLocal'以'Local'结尾等。有点脆弱,但是惯例可以用于例如。 JavaBeans的。 – 2013-03-19 09:24:53
谢谢Arjan。我同意 - 一些公约可能是一个解决方案。我猜这样的EJB视图识别可能只能使用服务器内部实现......如果可能的话! – 2013-03-19 18:36:06
不客气。如果您对EJB需要这种能力感到强烈,那么为什么不在http://java.net/jira/browse/EJB_SPEC上添加对它的功能请求? – 2013-03-19 20:04:23