2013-03-18 15 views
6

Si supponga che ho un EJB definisce due punti di vista:Scoprire cosa è stata utilizzata vista EJB

  • affari locale,
  • affari remoto.

Entrambe le interfacce condividono gli stessi metodi firme, quindi è come:

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

C'è un modo per capire cosa vista EJB è stato chiamato dall'interno della EJB sé (o il suo intercettore?)

Diciamo che vorrei eseguire procedure di autorizzazione diverse a seconda della vista utilizzata. Remote dovrebbe essere più limitato e locale non dovrebbe.

Posso invocare SessionContext#getInvokedBusinessInterface() ma questo mi dà informazioni solo sull'oggetto classe - non sulla semantica EJB di esso. Non è sufficiente usare la reflection per controllare la presenza di annotazioni su interfacce o bean (per quanto riguarda le viste definite in ejb-jar.xml?)

Dubito che sia possibile utilizzare specifiche EJB diritte ma forse c'è qualcosa che mi è sfuggito.

In caso contrario, è possibile ottenere queste informazioni dagli interni di un server delle applicazioni? (prendiamo in considerazione solo JBoss AS 7.x, Glassfish 3.xe TomEE 1.5.1).

+1

Il mio istinto dice che questo non è possibile in un modo portabile. Se lo è, ho perso qualcosa anch'io. Un trucco potrebbe essere utilizzare la convenzione delle interfacce di denominazione. Lo stai già facendo; 'MyBusinessLocal' termina con' Local' ecc. Un po 'fragile, ma le convenzioni funzionano per es. JavaBeans. –

+0

Grazie Arjan. Sono d'accordo: alcune convenzioni potrebbero essere una soluzione qui. Immagino che un tale riconoscimento delle viste EJB potrebbe essere possibile solo utilizzando internals del server ... Se è possibile a tutti! –

+0

Prego. Se ritieni fortemente che EJB necessiti di questa capacità, allora perché non aggiungere una richiesta di funzionalità per questo all'indirizzo http://java.net/jira/browse/EJB_SPEC? –

risposta

0

È proprio come ha detto Arjan: è impossibile farlo solo seguendo le specifiche EJB.

Tuttavia, in Glassfish è piuttosto semplice da fare.

Tutti gli interceptor EJB accettano il parametro InvocationContext. L'implementazione di InvocationContext in Glassfish è infatti la classe com.sun.ejb.EjbInvocation. Ha il campo isLocal che ti dice se intercetta chiamate commerciali locali (o isRemote per chiamate aziendali remote). Puoi usarlo per es. come segue:

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

Per accedere a questa classe di Glassfish interno EjbInvocation è necessario aggiungere seguente Maven dipendenza:

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

e potrebbe essere necessario aggiungere seguente repository specifica per ottenere l'accesso a questo artefatto:

Ho fatto una rapida ricerca (basata sul suggerimento di Richard riguardante l'oggetto Invocation) come ottenere lo stesso in JBoss ma non potevo d risposta ...