2013-03-18 4 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. Простое использование отражения для проверки присутствия аннотаций на интерфейсах или компонентах недостаточно (как насчет представлений, определенных в ejb-jar.xml?)

Я сомневаюсь, что это возможно, используя прямую спецификацию EJB, но, возможно, есть что-то, что я пропустил.

Если нет, возможно ли получить эту информацию от внутренних серверов приложений? (давайте рассмотрим только JBoss AS 7.x, Glassfish 3.x и TomEE 1.5.1).

+1

Мое ощущение кишки говорит, что это невозможно в переносном режиме. Если это так, я тоже что-то пропустил. Трюк может заключаться в использовании соглашения об именах интерфейсов. Вы уже это делаете; 'MyBusinessLocal' заканчивается' Local' и т. Д. Немного хрупкий, но соглашения работают, например. JavaBeans. –

+0

Спасибо Arjan. Я согласен - здесь может быть какое-то соглашение. Я предполагаю, что такое распознавание вида EJB может быть возможно только с использованием внутренних серверов ... Если это вообще возможно! –

+0

Добро пожаловать. Если вы чувствуете, что EJB нуждается в этой способности, то почему бы не добавить запрос функции для него по адресу http://java.net/jira/browse/EJB_SPEC? –

ответ

0

Это как раз то, что сказал Арьян - это невозможно сделать, следуя спецификации EJB.

Однако в Glassfish это довольно просто.

Все перехватчики EJB принимают параметр InvocationContext. InvocationContext реализация в Glassfish на самом деле 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 answer ...

Смежные вопросы