2013-03-18 31 views
6

假设我定义两种观点的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)。

+1

我的直觉告诉我们,这不可能以便携的方式进行。如果是这样,我也错过了一些东西。一个窍门可能是使用命名接口的约定。你已经这样做了; 'MyBusinessLocal'以'Local'结尾等。有点脆弱,但是惯例可以用于例如。 JavaBeans的。 – 2013-03-19 09:24:53

+0

谢谢Arjan。我同意 - 一些公约可能是一个解决方案。我猜这样的EJB视图识别可能只能使用服务器内部实现......如果可能的话! – 2013-03-19 18:36:06

+0

不客气。如果您对EJB需要这种能力感到强烈,那么为什么不在http://java.net/jira/browse/EJB_SPEC上添加对它的功能请求? – 2013-03-19 20:04:23

回答

0

就像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回答...

相关问题