2010-12-10 37 views
4

Je voudrais utiliser Spring en tant que fournisseur JNDI. Cela signifie que je voudrais configurer un bean dans mon contexte Spring, accessible via JNDI. Cela ressemblerait à quelque chose comme ceci:Le printemps en tant que fournisseur JNDI?

<bean class="org.some.thing.here"> 
    <property name="beans"> 
     <map> 
      <entry key="w/t/f"> 
       <bean class="some.thing.Else"> 
        // rest ommitted 
       </bean> 
      </entry> 
     </map> 
    </property> 
</bean> 

Puis, dans mon application (permet de dire un contrôleur), je veux être en mesure de saisir ce haricot via:

Context ctx = new InitialContext(); 
some.thing.Else bar = (some.thing.Else) ctx.lookup("w/t/f"); 

Comment pourrais-je aller à faire ce? J'ai regardé XBean, mais le projet semble obsolète (ne fonctionne pas avec Spring 3.0.X je ne pense pas), et il y a très peu de documentation.

D'autres options? Je voudrais aussi envisager de lancer ma propre classe de fournisseur jndi si ce n'est pas trop difficile à faire.

EDIT: Je devrais ajouter que je n'ai pas d'option en utilisant JNDI, j'ai une bibliothèque que nous devons utiliser qui nécessite que certains composants soient chargés via JNDI. Je voudrais utiliser Spring comme fournisseur.

+0

http://stackoverflow.com/questions/5974779/how-to-putbind-object-to-jndi-in-spring-declaratively – yetanothercoder

Répondre

4

Pourquoi utiliser JNDI? Obtenez juste le Spring ApplicationContext et obtenez le bean de cela.

En supposant que vous avez initialisé Spring en utilisant ContextLoaderListener dans votre webapp, vous devriez être capable de récupérer le contexte de l'application depuis le ServletContext. De là, vous pouvez obtenir n'importe quel haricot que vous avez déclaré au printemps.

ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext); 
Object bean = context.getBean(some.thing.Else.class); 

Si vous devez utiliser JDNI, vous pouvez créer un ServletContextListener qui fait quelque chose comme ce qui suit dans contextInitialized():

ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext); 

Object bean = context.getBean(some.thing.Else.class); 

Context initCtx = new InitialContext(); 
Context springCtx = initCtx.createSubcontext("spring"); 

springCtx.bind("bean", bean); 

Ensuite, vous devriez pouvoir recherche le bean Spring à "spring/bean" du InitialContext.

Deux choses à noter:

  1. L'auditeur de contexte devrait aussi appeler probablement initCtx.destroySubcontext ("printemps") en contextDestroy aussi. L'espace de noms java: comp/env est en lecture seule (dans Tomcat au moins), vous ne pouvez donc rien y mettre.


Asker modifier: Encore quelques points de clarté ...

Si vous envisagez de référence beans Spring via ApplicationContext, alors vous avez besoin d'un ContextLoaderListener défini dans votre web .xml. Cela doit être défini avant votre classe d'écouteur personnalisé ...comme ceci:

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

<listener> 
    <listener-class> 
    org.example.sandbox.MyCustomServletContextListener 
    </listener-class> 
</listener> 

En outre, vous pouvez obtenir le ServletContext que getWebApplicationContext utilise de la ServletContextEvent, comme ceci:

@Override 
public void contextInitialized(ServletContextEvent contextEvent) { 
    try { 
     ApplicationContext appContext = WebApplicationContextUtils.getWebApplicationContext(contextEvent.getServletContext()); 

     // get a bean named "myCalendar" from the application context  
     Calendar cal = (Calendar)appContext.getBean("myCalendar"); 

     // bind via JNDI 
     Context initialContext = new InitialContext(); 
     Context subCtx = initialContext.createSubcontext("sample"); 
     subCtx.bind("calendar", cal); 

    } catch (NamingException e) { // ommitted } 
} 
+0

Je suis obligé d'utiliser JNDI, je n'ai pas d'option. J'utilise une bibliothèque qui cherche divers composants à charger via JNDI. – Polaris878

+1

Pouvez-vous ajouter par programme des beans au JNDI initialContext? Si c'est le cas, vous pouvez écrire un ServletContextListener qui récupère le contexte de l'application printanière, récupère les beans et les place dans JNDI. – AngerClown

+0

AngerClown, c'est probablement ce que je cherche à faire, si vous avez des suggestions sur la façon de le faire, je serais très reconnaissant. – Polaris878

2

AngerClown est juste, ne vous embêtez pas avec JNDI sauf si vous devez fournir des références aux autres modules qui y insistent. Si vous êtes dans un conteneur webapp comme Tomcat, il aura un registre JNDI. Utiliser ça. Si ce n'est pas dans un conteneur webapp, cela n'a pas de sens d'avoir JNDI de toute façon, car c'est pour les environnements J2EE. En supposant que vous êtes dans une webapp, une meilleure façon de lancer votre application est d'avoir un bean Spring qui implémente des interfaces de cycle de vie (comme InitializingBean) pour recevoir un appel quand il est temps de démarrer votre application. À ce stade, votre classe d'application principale aura été injectée avec toutes ses dépendances. Cela évite d'avoir à appeler directement des méthodes sur ApplicationContext. Néanmoins, si vous devez appeler des méthodes sur ApplicationContext et que vous êtes lancé par Spring, vous pouvez implémenter BeanContextAware et être injecté avec le contexte.

+0

Oh, je vois les modifications maintenant pour le besoin JNDI Mais votre conteneur ne le fournit pas? –

+0

Oui, mais j'ai des tonnes de problèmes avec le conteneur de Tomcat, et il y a très peu de documentation ... J'ai pensé que je pourrais travailler avec quelque chose au printemps à la place (cela aurait plus d'informations) – Polaris878