2013-03-18 39 views
6

Załóżmy Mam EJB definiującą dwa widoki:dowiedzieć się, co widok EJB użyto

  • lokalnego biznesu,
  • Remote działalności.

Oba interfejsy te same podpisy metodzie, tak jak to jest:

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) { 
     // ... 
    } 
} 

Czy istnieje sposób, aby dowiedzieć się, co widok EJB nazwano od wewnątrz samego EJB (lub jego przechwytujących?)

Załóżmy, że chciałbym wykonać różne procedury autoryzacji w zależności od używanego widoku. Zdalny powinien być bardziej ograniczony, a lokalny nie powinien.

Mogę wywołać SessionContext#getInvokedBusinessInterface(), ale to daje mi informacje tylko o obiekcie klasy - nie o jego semantyki EJB. Proste używanie odbicia do sprawdzania obecności adnotacji na interfejsach lub fasoli nie jest wystarczające (co z widokami zdefiniowanymi w ejb-jar.xml?)

Wątpię, czy jest to możliwe przy użyciu prostej specyfikacji EJB, ale być może jest coś, co przeoczyłem.

Jeśli nie, to czy można uzyskać te informacje z wnętrza serwera aplikacji? (rozważmy tylko JBoss AS 7.x, Glassfish 3.x i TomEE 1.5.1).

+1

Moje przeczucie mówi, że nie jest to możliwe w przenośny sposób. Jeśli tak, to też coś przeoczyłem. Sztuczką może być użycie konwencji nazewnictwa interfejsów. Już to robisz; 'MyBusinessLocal' kończy się na' Local' itd. Trochę kruchy, ale konwencje działają np. JavaBeans. –

+0

Dzięki Arjan. Zgadzam się - pewna konwencja może być tutaj rozwiązaniem. Sądzę, że takie rozpoznawanie widoku EJB może być możliwe tylko przy użyciu wewnętrznych elementów serwera ... Jeśli to w ogóle możliwe! –

+0

Nie ma za co. Jeśli masz silne odczucie, że EJB potrzebuje tej umiejętności, dlaczego nie dodać do niej żądania funkcji na http://java.net/jira/browse/EJB_SPEC? –

Odpowiedz

0

To tak jak powiedział Arjan - nie można tego zrobić, wykonując specyfikację EJB.

Jednak w Glassfish jest to całkiem proste.

Wszystkie urządzenia przechwytujące EJB akceptują parametr InvocationContext. InvocationContext Implementacja w Glassfish jest w rzeczywistości klasą com.sun.ejb.EjbInvocation. Ma pole isLocal, które mówi, czy przechwytuje lokalne połączenie biznesowe (lub isRemote dla zdalnych wywołań biznesowych). Możesz go użyć np. w następujący sposób:

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."); 
     } 
    } 
} 

Aby uzyskać dostęp do tego EjbInvocation wewnętrzną klasę GlassFish trzeba dodać następujące zależność Maven:

<dependency> 
    <groupId>org.glassfish.main.ejb</groupId> 
    <artifactId>ejb-container</artifactId> 
    <version>4.0.1-b02</version> 
    <scope>provided</scope> 
</dependency> 

A może trzeba dodać następujące specyficzne repozytorium, aby uzyskać dostęp do tego artefaktu:

<repositories> 
    <repository> 
     <id>maven-promoted</id> 
     <url>https://maven.java.net/content/groups/promoted/</url> 
    </repository> 
</repositories> 

Zrobiłem szybkie badania (oparte na sugestii Richarda odnośnie obiektu Invocation), jak osiągnąć to samo w JBoss, ale nie mogłem d odpowiedz ...