Выяснение того, какой вид 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 ответ
Это как сказал Арджан - это невозможно сделать, просто следуя спецификации 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, но не смог найти ответ...