Come iniettare i bean Spring in una JSP 2.0 SimpleTag?
Domanda
Attualmente il mio tag jsp 2.0 che necessitano di fagioli primaverili utilizzare questo codice:
ac = WebApplicationContextUtils.getWebApplicationContext( servletContext);
ac.getBeansOfType(MyRequestedClass.class);
L'ottengo solo il primo chicco di corrispondenza.
Questo codice funziona bene, ma ha lo svantaggio indesiderato che trascorro circa la metà la mia pagina tempi di rendering alzando i fagioli di primavera, dal momento che questo accade ogni volta che un tag viene richiamato. Stavo pensando forse di mettere il fagiolo nel campo di applicazione o almeno ambito sessione. Ma ciò che è veramente il modo più intelligente di gestire questo problema?
Soluzione
Il mio primo pensiero è, sei sicuro che le chiamate verso la primavera sono costosi? Questa roba è piuttosto pesantemente ottimizzato, in modo da assicurarsi che sia in realtà un problema prima di provare a ottimizzarlo.
Supponendo che è un problema, allora alternativa è proprietà exposeContextBeansAsAttributes
e exposedContextBeanNames
di InternalResourceViewResolver
. È possibile utilizzare uno o l'altro (ma non entrambi) per esporre alcuni o tutti i fagioli come attributi JSP.
Ciò solleva le forse realmente di iniettare i bean Spring nelle vostre classi di tag. Ad esempio, nel vostro contesto primavera si può avere:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="exposeContextBeansAsAttributes" value="true"/>
</bean>
<bean id="myBean" class="com.x.MyClass"/>
Il tuo JSP:
<MyTag thing="${myBean}"/>
SO se MyTag
definisce un thing
attributo di tipo MyClass
, il fagiolo molla myBean
dovrebbe avere iniettato come attributo normale JSP.
Altri suggerimenti
Un modo più semplice sarebbe quella di utilizzare l'annotazione @Configurable sulla tua classe tag, questo renderebbe molla di legare automaticamente le dipendenze a quando il tag viene inizializzato. Eventuali dipendenze richieste possono poi essere contrassegnati con annotazione @AutoWired e Spring si cablare in dipendenza anche se l'etichetta non è inizializzato all'interno del contenitore della sorgente.
Un altro modo per raggiungere questo obiettivo è utilizzare una proprietà statica per contenere la dipendenza. Proprio come qui di seguito:
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;
}
}
In te ApplicationContext, è necessario registrare entrambi in modo che il tag JSP può ottenere una possibilità di essere avviata entro la primavera. Noi andiamo con la magia ...
<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 eh, ora aservice è visibile nel nostro tag JSP:)