Configurar con spring un api no basado en spring
Upcoming SlideShare
Loading in...5
×
 

Configurar con spring un api no basado en spring

on

  • 1,304 views

Muestra cómo configurar con Spring un proyecto web ItsNat.

Muestra cómo configurar con Spring un proyecto web ItsNat.
Los trucos empleados con Spring DI pueden ser aplicados a otros problemas similares.

Statistics

Views

Total Views
1,304
Views on SlideShare
1,296
Embed Views
8

Actions

Likes
0
Downloads
24
Comments
0

1 Embed 8

http://lanyrd.com 8

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Configurar con spring un api no basado en spring Configurar con spring un api no basado en spring Presentation Transcript

    • CONFIGURAR CON SPRING UN API NO BASADO EN SPRING Jose María Arranz Santamaría 17-18 Febrero 2011 1
    • EL PROBLEMA 2
    • EL PROBLEMA• Spring nació como una herramienta de configuración e integración de tecnologías dispares• No siempre podemos esperar que dichas tecnologías dispares se configuren necesariamente con Spring ¡Para eso existe Spring! 3
    • EL PROBLEMA• ItsNat es un framework web Java que tiene su propio sistema de configuración• ItsNat se configura de la forma más potente y flexible que existe A través de llamadas a métodos• Desde el día 0 se concibió para poder ser “sobrecargado” con APIs de más alto nivel, por ejemplo con… ¡Spring! 4
    • 5
    • TRANQUILO¡ESTA NO SERÁ UNA CLASE DE ItsNat!  6
    • APRENDEREMOS ALGUNOS TRUCOS DE Spring 7
    • PERO HAY QUE CONOCER CÓMO SE CONFIGURA ItsNat PARA APLICAR Spring 8
    • EJEMPLO ItsNat “PURO”: el servlet• ItsNat no define un servlet concreto, el usuario debe crear uno (o más) – Se configura en el método init • La inmensa mayoría de los flags de configuración usados son opcionales (coinciden con el valor por defecto)public class servlet extends HttpServletWrapper{ public void init(ServletConfig config) throws ServletException { super.init(config); ItsNatHttpServlet itsNatServlet = getItsNatHttpServlet(); ItsNatServletConfig itsNatConfig = itsNatServlet.getItsNatServletConfig(); ItsNatServletContext itsNatCtx = itsNatConfig.getItsNatServletContext(); 9
    • EJEMPLO ItsNat “PURO” : el servlet• ItsNatHttpServlet, ItsNatServletConfig y ItsNatServletContext son los objetos raíz de configuración en ItsNat itsNatCtx.setMaxOpenDocumentsBySession(6); String serverInfo = getServletContext().getServerInfo(); boolean gaeEnabled = serverInfo.startsWith( "Google App Engine"); itsNatCtx.setSessionReplicationCapable(gaeEnabled); itsNatCtx.setSessionSerializeCompressed(false); itsNatCtx.setSessionExplicitSerialize(false); 10
    • EJEMPLO ItsNat “PURO” : el servlet itsNatConfig.setDebugMode(true); itsNatConfig.setClientErrorMode( ClientErrorMode.SHOW_SERVER_AND_CLIENT_ERRORS); itsNatConfig.setLoadScriptInline(true); itsNatConfig.setFastLoadMode(true); itsNatConfig.setCommMode(CommMode.XHR_ASYNC_HOLD); itsNatConfig.setEventTimeout(-1); itsNatConfig.setOnLoadCacheStaticNodes("text/html",true); itsNatConfig.setOnLoadCacheStaticNodes("text/xml",false); itsNatConfig.setNodeCacheEnabled(true); 11
    • EJEMPLO ItsNat “PURO” : el servletitsNatConfig.setDefaultEncoding("UTF-8");itsNatConfig.setUseGZip(UseGZip.SCRIPT);itsNatConfig.setDefaultDateFormat( DateFormat.getDateInstance(DateFormat.DEFAULT,Locale.US));itsNatConfig.setDefaultNumberFormat( NumberFormat.getInstance(Locale.US));itsNatConfig.setEventDispatcherMaxWait(0);itsNatConfig.setEventsEnabled(true);itsNatConfig.setScriptingEnabled(true);itsNatConfig.setUsePatternMarkupToRender(false);itsNatConfig.setAutoCleanEventListeners(true); 12
    • EJEMPLO ItsNat “PURO” : el servlet• Ahora registramos en el servlet un template core_example.xhtml con su procesador de carga CoreExampleLoadListener – Ejemplo sencillo de página HTML con AJAX String pathPrefix = getServletContext().getRealPath("/"); pathPrefix += "/WEB-INF/pages/manual/"; ItsNatDocumentTemplate docTemplate; docTemplate = itsNatServlet.registerItsNatDocumentTemplate( "manual.core.example","text/html", pathPrefix + "core_example.xhtml"); docTemplate.addItsNatServletRequestListener( new CoreExampleLoadListener()); 13
    • EJEMPLO ItsNat “PURO” : el servlet• Y otro ejemplo de generación de página XML docTemplate = itsNatServlet.registerItsNatDocumentTemplate( "manual.core.xmlExample","text/xml", pathPrefix + "xml_example.xml"); docTemplate.addItsNatServletRequestListener( new CoreXMLExampleLoadListener());• Que a su vez inserta un template fragment – Los template fragment no tienen procesador ItsNatDocFragmentTemplate docFragTemplate; docFragTemplate = itsNatServlet.registerItsNatDocFragmentTemplate( "manual.core.xmlFragExample","text/xml", pathPrefix + "xml_fragment_example.xml"); 14
    • EJEMPLO ItsNat “PURO”• <root>/WEB-INF/pages/manual/core_example.xhtml<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>ItsNat Core Example</title></head><body> <h3>ItsNat Core Example</h3> <div itsnat:nocache="true" xmlns:itsnat="http://itsnat.org/itsnat"> <div id="clickableId1">Clickable Elem 1</div> <br /> <div id="clickableId2">Clickable Elem 2</div> </div></body></html> 15
    • EJEMPLO ItsNat “PURO”• CoreExampleLoadListener es un mero lanzador del gestor del documento en cada carga de páginapublic class CoreExampleLoadListener implements ItsNatServletRequestListener{ public CoreExampleLoadListener() {} public void processRequest(ItsNatServletRequest request, ItsNatServletResponse response) { ItsNatHTMLDocument itsNatDoc = (ItsNatHTMLDocument)request.getItsNatDocument(); new CoreExampleDocument(itsNatDoc); }} 16
    • EJEMPLO ItsNat “PURO”• CoreExampleDocument gestiona el estado de la página recibiendo los eventos AJAXpublic class CoreExampleDocument implements EventListener{ protected ItsNatHTMLDocument itsNatDoc; protected Element clickElem1; protected Element clickElem2; public CoreExampleDocument(ItsNatHTMLDocument itsNatDoc) { this.itsNatDoc = itsNatDoc; load(); } ... 17
    • EJEMPLO ItsNat “PURO” 18
    • EJEMPLO ItsNat “PURO”• <root>/WEB-INF/pages/manual/xml_example.xml<?xml version=1.0 encoding=UTF-8 ?><discs> <itsnat:include name="manual.core.xmlFragExample" xmlns:itsnat="http://itsnat.org/itsnat" /> <cdList> <cd> <title>Tittle</title> <artist>Artist</artist> <songs> <song>Song Pattern</song> </songs> </cd> </cdList></discs> 19
    • EJEMPLO ItsNat “PURO”• <root>/WEB-INF/pages/manual/xml_fragment_example.xml<?xml version=1.0 encoding=UTF-8 ?><root> <title>CD List</title> <subtitle>in XML</subtitle></root> 20
    • EJEMPLO ItsNat “PURO”• CoreXMLExampleLoadListener : como en XML no hay AJAX no necesitamos una clase wrapper de documento. Se incluye el template fragment manual.core.xmlFragExamplepublic class CoreXMLExampleLoadListener implements ItsNatServletRequestListener{ public CoreXMLExampleLoadListener() { } public void processRequest(ItsNatServletRequest request, ItsNatServletResponse response) { ItsNatDocument itsNatDoc = request.getItsNatDocument(); Document doc = itsNatDoc.getDocument(); Element discsElem = doc.getDocumentElement(); ... 21
    • EJEMPLO ItsNat “PURO” 22
    • ItsNat Springization 23
    • OBJETIVOS1. Un único servlet genérico reutilizable: itsnatspring.itsnatservlet2. La configuración se realizará totalmente en un archivo XML de Spring en el classpath: itsnatex/spring.xml3. Las únicas clases del usuario serán las clases contenedoras del documento ItsNat (=página): itsnatex.CoreExampleDocument itsnatex.CoreXMLExampleDocument 24
    • CONSECUENCIAS• Además del servlet genérico reutilizable necesitaremos una serie de clases de utilidad también genéricas y reutilizables• Dichas clases quedarán incompletas, sólo cubriremos las necesidades de este ejemplo – ItsNat tiene más métodos de configuración 25
    • EL SERVLETpackage itsnatspring;import javax.servlet.ServletConfig;import javax.servlet.ServletException;import org.itsnat.core.http.HttpServletWrapper;import org.itsnat.core.http.ItsNatHttpServlet;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.springframework.context.support.GenericApplicationContext;public class itsnatservlet extends HttpServletWrapper{ public void init(ServletConfig config) throws ServletException { super.init(config); ItsNatHttpServlet itsNatServlet = getItsNatHttpServlet(); GenericApplicationContext rootContext = new GenericApplicationContext(); ItsNatBeansRegistryUtil.registerSingletons(rootContext, itsNatServlet); rootContext.refresh(); 26
    • EL SERVLET String springXMLPath = config.getInitParameter("spring_config"); if (springXMLPath == null) throw new RuntimeException("spring_config initialization parameter is not specified in web.xml"); ApplicationContext context = new ClassPathXmlApplicationContext( new String[] {springXMLPath},rootContext); }}• Se registran como singleton los objetos de configuración de ItsNat en un ApplicationContext genérico raíz y se carga en otro nuevo nuestro XML Spring 27
    • ItsNatBeansRegistryUtilpackage itsnatspring;import org.itsnat.core.ItsNatServletConfig;import org.itsnat.core.ItsNatServletContext;import org.itsnat.core.http.ItsNatHttpServlet;import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;import org.springframework.context.ApplicationContext;import org.springframework.context.support.AbstractApplicationContext;public class ItsNatBeansRegistryUtil{ public final static String itsNatHttpServletBean = "itsNatHttpServlet"; public final static String itsNatServletConfigBean = "itsNatServletConfig"; public final static String itsNatServletContextBean = "itsNatServletContext"; public static ItsNatHttpServlet getItsNatHttpServlet(ApplicationContext context) { return context.getBean(itsNatHttpServletBean,ItsNatHttpServlet.class); } public static ItsNatServletConfig getItsNatServletConfig(ApplicationContext context){ return context.getBean(itsNatServletConfigBean,ItsNatServletConfig.class); } public static ItsNatServletContext getItsNatServletContext(ApplicationContext context){ return context.getBean(itsNatServletContextBean,ItsNatServletContext.class); } 28
    • ItsNatBeansRegistryUtil public static void registerSingletons(AbstractApplicationContext context, ItsNatHttpServlet itsNatServlet) { ItsNatServletConfig itsNatServletCofig = itsNatServlet.getItsNatServletConfig(); ItsNatServletContext itsNatServletContext = itsNatServletCofig.getItsNatServletContext(); ConfigurableListableBeanFactory beanFact = context.getBeanFactory(); beanFact.registerSingleton(itsNatHttpServletBean,itsNatServlet); beanFact.registerSingleton(itsNatServletConfigBean,itsNatServletCofig); beanFact.registerSingleton(itsNatServletContextBean,itsNatServletContext); }}• El resultado es el registro manual como singleton de los objetos de conf. de ItsNat 29
    • web.xml<?xml version="1.0" encoding="UTF-8"?><web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <servlet> <servlet-name>itsnatservlet</servlet-name> <servlet-class>itsnatspring.itsnatservlet</servlet-class> <init-param> <param-name>spring_config</param-name> <param-value>itsnatex/spring.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>itsnatservlet</servlet-name> <url-pattern>/itsnatservlet</url-pattern> </servlet-mapping> <session-config> <session-timeout>30</session-timeout> </session-config></web-app> 30
    • spring.xml<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"><bean class="itsnatspring.ItsNatServletContextBean"> <property name="maxOpenDocumentsBySession" value="10" /> <property name="sessionReplicationCapable" value="false" /> <property name="sessionSerializeCompressed" value="false" /> <property name="sessionExplicitSerialize" value="false" /></bean> 31
    • ItsNatServletContextBean• Este bean singleton de utilidad nos sirve para recordar los flags definidos y al final registrarlos de forma efectiva en el ItsNatServletContext – Como se necesita el ApplicationContext implementamos ApplicationContextAware – Como necesitamos actuar cuando termine la configuración del bean, implementamos InitializingBean 32
    • ItsNatServletContextBeanpackage itsnatspring;import org.itsnat.core.ItsNatServletContext;import org.springframework.beans.BeansException;import org.springframework.beans.factory.InitializingBean;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;public class ItsNatServletContextBean implements InitializingBean,ApplicationContextAware{ protected ApplicationContext context; protected Integer maxOpenDocumentsBySession; protected Boolean sessionReplicationCapable; protected Boolean sessionSerializeCompressed; protected Boolean sessionExplicitSerialize; public ItsNatServletContextBean() { } 33
    • ItsNatServletContextBeanpublic int getMaxOpenDocumentsBySession() { return maxOpenDocumentsBySession;}public void setMaxOpenDocumentsBySession(int maxOpenDocumentsBySession){ this.maxOpenDocumentsBySession = maxOpenDocumentsBySession;}public boolean getSessionReplicationCapable() { return sessionReplicationCapable;}public void setSessionReplicationCapable( boolean sessionReplicationCapable) { this.sessionReplicationCapable = sessionReplicationCapable;}public boolean getSessionSerializeCompressed() { return sessionSerializeCompressed;}public void setSessionSerializeCompressed( boolean sessionSerializeCompressed) { this.sessionSerializeCompressed = sessionSerializeCompressed;} 34
    • ItsNatServletContextBean public boolean getSessionExplicitSerialize() { return sessionExplicitSerialize; } public void setSessionExplicitSerialize(boolean sessionExplicitSerialize){ this.sessionExplicitSerialize = sessionExplicitSerialize; } @Override public void setApplicationContext(ApplicationContext context) throws BeansException { this.context = context; } @Override public void afterPropertiesSet() throws Exception { ItsNatServletContext itsNatServletContext = ItsNatBeansRegistryUtil.getItsNatServletContext(context); if (maxOpenDocumentsBySession != null) itsNatServletContext.setMaxOpenDocumentsBySession(maxOpenDocumentsBySession); if (sessionReplicationCapable != null) itsNatServletContext.setSessionReplicationCapable(sessionReplicationCapable); if (sessionSerializeCompressed != null) itsNatServletContext.setSessionSerializeCompressed(sessionSerializeCompressed); if (sessionExplicitSerialize != null) itsNatServletContext.setSessionExplicitSerialize(sessionExplicitSerialize); }} 35
    • spring.xml (cont.)<bean id="defaultLocale" class="itsnatspring.LocaleBean" > <property name="language" value="en" /> <property name="country" value="US" /></bean><bean id="defaultDateFormat" class="itsnatspring.DateFormatBean" > <property name="style" value="2" /> <!-- DateFormat.DEFAULT --> <property name="locale"> <bean factory-bean="defaultLocale" factory-method="getLocale"/> </property></bean><bean id="defaultNumberFormat" class="itsnatspring.NumberFormatBean" > <property name="locale"> <bean factory-bean="defaultLocale" factory-method="getLocale" /> </property></bean>... 36
    • LocaleBean• Este “factory bean” nos permite configurar un objeto y hacerlo público a través del “factory method” getLocale()package itsnatspring;import java.util.Locale;import org.springframework.beans.factory.InitializingBean;public class LocaleBean implements InitializingBean{ protected String language; protected String country; protected Locale locale; public LocaleBean() { } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public String getLanguage() { return language; } 37
    • LocaleBean public void setLanguage(String language) { this.language = language; } public Locale getLocale() { return locale; } @Override public void afterPropertiesSet() throws Exception { Locale[] availablelocales = Locale.getAvailableLocales(); for(Locale locale : availablelocales) if (locale.getLanguage().equals(language) && locale.getCountry().equals(country)) { this.locale = locale; return; } this.locale = new Locale(language,country); }} 38
    • • Desde ahora sólo mostraremos las clases de utilidad más interesantes• A partir del XML puede intuirse la funcionalidad de las demás – Obteniéndose los singleton de configuración de ItsNat a través del ApplicationContext – El cual es obtenido implementando ApplicationContextAware 39
    • spring.xml (cont.)<bean class="itsnatspring.ItsNatServletConfigBean"> <property name="debugMode" value="true" /> <property name="clientErrorMode" value="4" /> <!– ClientErrorMode.SHOW_SERVER_AND_CLIENT_ERRORS --> <property name="defaultEncoding" value="UTF-8" /> <property name="onLoadCacheStaticNodes"> <value> text/html=true text/xml=false </value> </property> <property name="defaultDateFormat"> <bean factory-bean="defaultDateFormat" factory-method="getDateFormat"/> </property> <property name="defaultNumberFormat"> <bean factory-bean="defaultNumberFormat" factory-method="getNumberFormat"/> </property></bean> ... 40
    • spring.xml (cont.)<bean id="coreExamplePath" class="itsnatspring.WebPathBean"> <property name="relativePath" value="/WEB-INF/pages/manual/core_example.xhtml"/></bean><bean id="coreExampleDoc" class="itsnatex.CoreExampleDocument" scope="prototype" > <!-- Globals Here --></bean><bean id="coreExampleDocTemplate" class="itsnatspring.ItsNatDocumentTemplateBean"> <property name="name" value="manual.core.example" /> <property name="mime" value="text/html" /> <property name="source"> <bean factory-bean="coreExamplePath" factory-method="getAbsolutePath"/> </property> <property name="itsNatServletRequestListener" > <bean class="itsnatspring.ItsNatServletRequestListenerBean" > <property name="documentBeanName" value="coreExampleDoc" /> </bean> </property></bean> ... 41
    • ItsNatServletRequestListenerBean• Este bean es MUY interesante pues actúa como “ItsNat document loader listener” genérico• Nos obligará a que la clase procesadora del documento implemente una sencilla interfaz especial llamada: ItsNatDocumentInitializepackage itsnatspring;import org.itsnat.core.ItsNatServletRequest;import org.itsnat.core.ItsNatServletResponse;public interface ItsNatDocumentInitialize{ public void load(ItsNatServletRequest request, ItsNatServletResponse response);} 42
    • ItsNatServletRequestListenerBeanpackage itsnatspring;import org.itsnat.core.ItsNatServletRequest;import org.itsnat.core.ItsNatServletResponse;import org.itsnat.core.event.ItsNatServletRequestListener;import org.springframework.beans.BeansException;import org.springframework.beans.factory.InitializingBean;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.context.support.AbstractApplicationContext;public class ItsNatServletRequestListenerBean implements ItsNatServletRequestListener,ApplicationContextAware,InitializingBean{ protected AbstractApplicationContext context; protected String documentBeanName; public ItsNatServletRequestListenerBean() { } 43
    • ItsNatServletRequestListenerBeanpublic void processRequest(ItsNatServletRequest request, ItsNatServletResponse response) { ItsNatDocumentInitialize docWrapper = context.getBean(documentBeanName,ItsNatDocumentInitialize.class); docWrapper.load(request, response); } public String getDocumentBeanName() { return documentBeanName; } public void setDocumentBeanName(String documentBeanName) { this.documentBeanName = documentBeanName; } 44
    • ItsNatServletRequestListenerBean @Override public void setApplicationContext(ApplicationContext context) throws BeansException { this.context = (AbstractApplicationContext)context; } @Override public void afterPropertiesSet() throws Exception { // Checking correctly defined: if (documentBeanName == null) throw new RuntimeException("docBeanName property is mandatory"); if (!context.getBeanFactory().isPrototype(documentBeanName)) throw new RuntimeException("Bean " + documentBeanName + " must be "prototype" scoped"); }} 45
    • ItsNatDocumentTemplateBean• Finalmente este bean registrará en el template el “ItsNat document loader listener” configuradopackage itsnatspring;import org.itsnat.core.event.ItsNatServletRequestListener;import org.itsnat.core.http.ItsNatHttpServlet;import org.itsnat.core.tmpl.ItsNatDocumentTemplate;import org.springframework.beans.BeansException;import org.springframework.beans.factory.InitializingBean;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;public class ItsNatDocumentTemplateBean implements InitializingBean,ApplicationContextAware { protected ApplicationContext context; protected String name; protected String mime; protected Object source; protected ItsNatServletRequestListener itsNatServletRequestListener; 46
    • ItsNatDocumentTemplateBean public ItsNatServletRequestListener getItsNatServletRequestListener(){ return itsNatServletRequestListener; } public void setItsNatServletRequestListener( ItsNatServletRequestListener itsNatServletRequestListener) { this.itsNatServletRequestListener = itsNatServletRequestListener; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMime() { return mime; } public void setMime(String mime) { this.mime = mime; } public Object getSource() { return source; } public void setSource(Object source) { this.source = source; }@Override public void setApplicationContext(ApplicationContext context) throws BeansException { this.context = context; } 47
    • ItsNatDocumentTemplateBean @Override public void afterPropertiesSet() throws Exception { // name, mime and source are mandatory ItsNatHttpServlet itsNatHttpServlet = ItsNatBeansRegistryUtil.getItsNatHttpServlet(context); ItsNatDocumentTemplate docTemplate = itsNatHttpServlet.registerItsNatDocumentTemplate(name,mime,source); if (itsNatServletRequestListener != null) docTemplate.addItsNatServletRequestListener( itsNatServletRequestListener); // More config here... }} 48
    • spring.xml (cont.)<bean id="coreXMLDocExamplePath" class="itsnatspring.WebPathBean"> <property name="relativePath" value="/WEB-INF/pages/manual/xml_example.xml" /></bean><bean id="coreXMLExampleDoc" class="itsnatex.CoreXMLExampleDocument“ scope="prototype"> <!-- Globals Here --></bean><bean id="coreXMLExampleDocTemplate" class="itsnatspring.ItsNatDocumentTemplateBean"> <property name="name" value="manual.core.xmlExample" /> <property name="mime" value="text/xml" /> <property name="source"> <bean factory-bean="coreXMLDocExamplePath" factory-method="getAbsolutePath"/> </property> <property name="itsNatServletRequestListener" > <bean class="itsnatspring.ItsNatServletRequestListenerBean" > <property name="documentBeanName" value="coreXMLExampleDoc" /> </bean> </property></bean> ... 49
    • spring.xml (cont.)<bean id="coreXMLFragExamplePath" class="itsnatspring.WebPathBean"> <property name="relativePath" value="/WEB-INF/pages/manual/xml_fragment_example.xml" /></bean><bean id="coreXMLExampleFragTemplate" class="itsnatspring.ItsNatDocFragmentTemplateBean"> <property name="name" value="manual.core.xmlFragExample" /> <property name="mime" value="text/xml" /> <property name="source"> <bean factory-bean="coreXMLFragExamplePath" factory-method="getAbsolutePath"/> </property></bean></beans> 50
    • ItsNatDocFragmentTemplateBean• Con ella registramos un template fragment...public class ItsNatDocFragmentTemplateBean implements InitializingBean,ApplicationContextAware{ protected ApplicationContext context; protected String name; protected String mime; protected Object source;... @Override public void afterPropertiesSet() throws Exception { // name, mime and source are mandatory ItsNatHttpServlet itsNatHttpServlet = ItsNatBeansRegistryUtil.getItsNatHttpServlet(context); ItsNatDocFragmentTemplate fragTemplate; fragTemplate = itsNatHttpServlet.registerItsNatDocFragmentTemplate( name,mime,source); // More config here... }} 51
    • CONCLUSIÓN¿Puedes integrar Spring para configurar “cualquier” API? 52
    • YES, YOU CAN! 53
    • ¿PREGUNTAS? 54