2009-08-18 11 views
13

Actuellement mes jsp 2.0 balises qui ont besoin d'haricots de printemps utilisent ce code:Comment injecter des haricots de printemps dans un jsp 2.0 SimpleTag?

ac = WebApplicationContextUtils.getWebApplicationContext(servletContext); 
ac.getBeansOfType(MyRequestedClass.class); 

Le Je viens d'obtenir le premier haricot correspondant.

Ce code fonctionne correctement, mais il présente l'inconvénient indésirable que je passe environ la moitié de mon temps de rendu des pages à rechercher des haricots de printemps, car cela se produit chaque fois qu'une étiquette est invoquée. Je pensais peut-être à mettre le bean dans la portée de l'application ou au moins dans la portée de la session. Mais quelle est la manière la plus intelligente de gérer ce problème?

+0

« [http://stackoverflow.com/questions/3445908/is-there- un-moyen-élégant-d'injecter-un-géré-bean-dans-dans-un-java-custom-simpl] [1] 'a une bonne réponse pour cela. [1]: http://stackoverflow.com/questions/3445908/is-there-an-elegant-way-to-inject-a-spring-managed-bean-into-a-java- custom-simple – Angus

Répondre

11

Ma première pensée est, êtes-vous sûr que les appels au printemps sont chers? Ce matériel est très optimisé, alors assurez-vous que c'est réellement un problème avant d'essayer de l'optimiser.

Si l'on suppose qu'il est un problème, une alternative est le exposeContextBeansAsAttributes et exposedContextBeanNames propriétés de InternalResourceViewResolver. Vous pouvez utiliser l'un ou l'autre (mais pas les deux) pour exposer tout ou partie de vos beans en tant qu'attributs JSP.

Ceci augmente la possibilité d'injecter des beans Spring dans vos classes d'étiquettes. Par exemple, dans votre contexte de printemps, vous pouvez:

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
    <property name="exposeContextBeansAsAttributes" value="true"/> 
</bean> 

<bean id="myBean" class="com.x.MyClass"/> 

Votre JSP:

<MyTag thing="${myBean}"/> 

SO si MyTag définit un attribut thing de type MyClass, la fève de printemps myBean devrait s'injecter comme JSP normale attribut.

+0

Oui, ils sont relativement chers. Surtout que les tags sont utilisés dans les boucles. Nous parlons de 1-200 appels à la logique mentionnée ci-dessus en utilisant 60-70% de mon temps d'exécution. Le reste du code est propre et élégant. – krosenvold

8

Une méthode plus simple consisterait à utiliser l'annotation @Configurable sur votre classe d'étiquettes, ce qui permettrait à Spring de câbler automatiquement les dépendances lorsque la balise est initialisée. Toutes les dépendances requises peuvent ensuite être étiquetées avec l'annotation @AutoWired et Spring connectera dans la dépendance même si la balise n'est pas initialisée dans le conteneur Spring.

+0

Pourriez-vous s'il vous plaît développer? Merci –

5

Une autre façon d'y parvenir est d'utiliser une propriété statique pour contenir la dépendance. Tout comme ci-dessous:

public class InjectedTag extends SimpleTagSupport { 
//In order to hold the injected service, we have to declare it as static 
    private static AService _service; 
/***/ 
@Override 
public void doTag() throws IOException {  
      getJspContext().getOut(). 
      write("Service injected: " + _service + "<br />");  
} 
public void setService(AService service) { 
     _service = service;  
} 
} 

En vous applicationContext, vous devez vous enregistrer à la fois afin que la balise JSP peut obtenir une chance d'être initié au printemps. Nous nous allons avec la magie ...

<bean id="aService" class="com.foo.AService"> 
    <!-- configure the service. --> 
</bean> 
<bean class="com.foo.InjectedTag" > 
    <property name="service"><ref local="aService"/></property> 
</bean> 

cool hein, maintenant aservice est visible dans notre balise JSP :)