2010-10-01 31 views
3

ici est ma mise en œuvre de DAO, je vais charger toute la table et mises en mémoire cache pendant une certaine période de tempsCDI intercepteurs d'appel méthode annotée au sein même instance

@ApplicationScoped 
public class DataAccessFacade { 

    @Inject 
    private EntityManager em; 

    @CacheOutput 
    public Map<String, String> loadAllTranslation() { 
     List<Translation> list = em.createQuery("select t from Translation t").getResultList();  
     Map<String, String> result = new HashMap<String, String>(); 
     // do more processing here, omitted for clarity  
     return result; 
    } 

    public String getTranslation(String key) { 
     return loadAllTranslation().get(key); 
    } 

} 

ici est mon client jersey

@Inject 
DataAccessFacade dataAccessFacade; 

@Path("/5") 
@GET 
@Produces(MediaType.TEXT_PLAIN) 
public String t5(@QueryParam("id") String key) { 
    // load the data from dataAccessFacade 
    String text = dataAccessFacade.getTranslation(key); 
    String text2 = dataAccessFacade.loadAllTranslation().get(key); 
} 

dans le client si j'appelle le dataAccessFacade.loadAllTranslation(), je vais voir la logique intercepteur été exécutée

si j'appelle le dataAccessFacade.getTranslation() qui interne appelez le loadAllTranslation(), puis je n'ai pas vu l'intercepteur été exécuté

quel est le problème ici?

comment le résoudre? Un intercepteur lié à une classe intercepte toutes les méthodes.

Répondre

-1

Il semble que vous ayez choisi de lier votre intercepteur (@CacheOutput?) À des méthodes spécifiques plutôt qu'au niveau de la classe.

J'imagine que si vous avez explicitement lié votre intercepteur à la méthode getTranslation en plus de loadAllTranslation, alors vous verrez l'intercepteur fonctionner dans les deux situations.

Je n'ai trouvé aucune explication dans la spécification pour expliquer le comportement actuel. Je suppose qu'il pourrait être considéré comme une sorte d'encapsulation (dissimulation d'informations). Extérieurement, il n'y a aucune raison de s'attendre à ce qu'un appel à getTranslation entraîne un appel à loadAllTranslation. Si l'intercepteur devait être appelé à la suite d'un appel à getTranslation (sans une annotation explicite), il pourrait être perçu comme une fuite des détails du fonctionnement interne de la classe.

+0

j'ai essayé de déplacer l'annotation au niveau de la classe, même résultat. – Dapeng

+0

Pas vraiment sûr. Pourriez-vous essayer cet intercepteur métier très simple et voir ce que vous obtenez: http://www.easybeans.org/doc/userguide/en/chunk-integrated/ch04s04.html –

2

C'est le comportement correct comme dans la spécification CDI. Seules les méthodes appelées par les classes "client" sont considérées comme des "méthodes métier" et sont donc interceptées.

1

Il suffit de faire ce qui suit dans votre DataAccessFacade:

@Inject 
private Provider<DataAccessFacade> self; 

public String getTranslation(String key) { 
    return self.get().loadAllTranslation().get(key); 
} 
+0

Et si nous ne savons pas comment l'objet a été injecté ? Il peut s'agir d'une sous-classe et/ou de qualificatifs au point d'injection. Y a-t-il un moyen d'obtenir le même objet que le client voit? – marcus