2013-03-18 24 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回答...