mercredi 5 décembre 2007

Injection d’un EJB dans un back bean JSF 1.1

Dans sa version 10.1, BEA workshop studio propose de base de faire du JSF 1.1. Or, dans la spécification JSF 1.1, l’injection d’EJB n’est pas possible dans les back-beans.

En attendant la nouvelle version de workshop qui devrait permettre d’utiliser JSF 1.2 facilement (oui c’est déjà possible mais galère) et donc l’injection dans les back beans, je vous propose un petit « hack » maison pour permettre de ne pas trop salir vos managed beans tout en ayant un semblant d’injection (Le canada dry de l'injection EJB).

Le fonctionnement est simple, on crée un servlet listener qui possède une référence vers tous les ejb que vous utiliserez dans l’application. La norme JSF 1.1 permettant l’injection dans les servletfilters, ces références seront peuplées lors de l’exécution. Dès lors, notre tâche consistera à copier les références dans le servletcontext pour que nos back beans aient accès aux valeurs injectées.

Je vous fourni donc une classe qui par réflexion va analyser tous les champs public qui contiennent l’annotation @EJB et qui écrira (pour le listener) ou lira (pour le back bean) la valeur dans le ServletContext.

Utilisation :

Notre Listener comportra une réference vers tous les EJB utilisés (un seul dans mon exemple), et l'implémentation de la méthode contextInitialized sera toute simple :

public class testEJBInjectionListener implements ServletContextListener {

@EJB(name = "Addition/Local")

public AdditionRemote ar;

public void contextDestroyed(ServletContextEvent arg0) {

// TODO Auto-generated method stub

}

public void contextInitialized(ServletContextEvent arg0) {

tools.EJB_Initialiser.saveMyEJBs(arg0.getServletContext(),this);

}

}




Du coté du back bean, rien de plus compliqué. On fait une référence vers les EJB que l'on souhaite utiliser en conservant l'injection :

public class testBackBean {

@EJB(name = "Addition/Local")

public AdditionRemote ar;

public testBackBean()

{

tools.EJB_Initialiser.injecterMesEJB(this);

}

}


La classe utilitaire InitialiserEJB fesant le reste : télécharger la classe.

Au niveau des performances ce n'est pas terrible du tout car cela effectue un lock sur l'instance des l'EJB coté serveur (car une seule instance dans le contexte application), aucun accès concurant ne sera donc possible et il faudra attendre gentiment son tour pour accéder au bean session. A utiliser donc en attendant JSF 1.2 !

1 commentaire:

littlewing a dit…

Je ne pense meme pas que c est a utiliser "en attendant". Expression qu'il est interdit d utiliser sachant que 90% du temps, les solutions temporaires sont utilisees a long terme :-) ...en production
Des locks de ce genre peuvent provoquer des ralentissements, des deadlocks ou encore des exceptions pour les EJB stateful.
A mon avis la solution a prendre en consideration est de faire le lookup a la mimine sur l interface locale.