SlideShare una empresa de Scribd logo
1 de 159
Introducción al Framework Spring
Spring es un framework ligeropara el desarrollo de aplicaciones. Strtus, WebWork y otros son frameworks para web. Spring, por contra, dasoporte a todaslascapas de unaaplicación.  Nosevita “la fontanería” quenormalmente el desarrollador se veobligado a implementara mano. ¿Quées Spring?
Publicado en 2002/2003 por Rod Johnson y JuergenHoller Empezósiendo un ejemplo en el libroExpert One-on-One J2EE Design and Development de Rod Johnson. Spring 1.0 se publica en marzo del 2004 A partir de 2004/2005 Spring se popularizacomo framework de desarrolloparaaplicaciones Java/J2EE Historia de Spring…
Spring no es un servidor de aplicaciones JEE, sinoque se integra en lasaplicacionesque se despliegansobreellos, y sobreaplicaciones Java en general. Spring sustituye ¿elegantemente? algunosde los serviciosqueaportan los servidores de aplicaciones JEE. ¿Spring & JEE?
Spring propone unaestructuraconsistenteparatoda la aplicación Facilita un métodoconsistenteparapegartodos los elementos de la aplicación. Abierto a la integración con múltiplesestándares e implementacionespopularescomo: Hibernate, JDO, TopLink, EJB, RMI, JNDI, JMS, Web Services, Struts, etc. Permiteaumentarnuestraproductividadevitándo al desarrollador la tarea de implementartareasderivadas de la integración de los componentes de la aplicación. ¿Quéaporta Spring?
From springframework.org Los creadores de Spring defiendenque: JEE debería ser mássencilla de usar Es preferibleprogramar interfaces a programarclases, peroéstoconllevausualmente un costeadicional de implementación. Spring lo facilitareduciendo la implementacióndesacopladabasándose en interfaces. La especificación de JavaBeans ofrececiertasventajas a la hora de externalizar y modularizar la configuración de lasaplicaciones. El paradigma OO debeimponersesobre la tecnologíasubyacentecomo _JEE Filosofíade Spring
Filosofía POJO, menos interfaces y excepcioneschequeadasquefuerzan a complicar el códigocuandointegramoselementosdiferentes. La prueba del software son esenciales. Spring nosayuda a implementarcódigochequeablemediantepruebasunitarias. La aplicación de Spring debe ser placentera. El código de la aplicación no debedepender de las APIs de Spring. Spring no debecompetir con solucionesqueyafuncionan, sinopermitirsufácilintegración en la aplicación (Ej, Hibernate, JDO, etc.) Filosofíade Spring
Arquitectura from springframework.org
¿Quéimplicaesto? No fuerza a importar o extender ninguna API de Spring. Unatecnologíainvasivacomprometenuestrocódigo con susimplementaciones- Anti-patrones: EJB nosfuerza a usar JNDI Struts 1.x fuerza a extender la claseAction Los Frameworks invasivos son por lo general difíciles de testear.   Tecnología no invasiva
Fundamentalmente, Spring se compone de: Contenedor de inversión de control (IoC) Aplicación de la técnica de inyección de dependencias (Fowler) Un framework AOP. Spring facilita un framework AOP basado en proxy. Integrable con AspectJ o AspectWerkz Unacapa de abstracción de servicios Integraciónconsistente con variosestándares y APIs populares. Todoelloestábasado en la implementación de aplicacionesusando POJOs. Estructura de Spring
Spring IoCContainerInyección de dependencias
Gestiona objetos como componentes, permitiendo: Crearlos Configurarlos “Cablearlos” (Wiring) – Enlazado entre objetos. Controlar todo si ciclo de vida Controlar su destrucción Ofrece varios tipos de contenedor diferentes, clasificables en dos tipos: BeanFactory ApplicationContext (más completo) ¿Para qué vale?
Descarguemos el piloto 1.0 y analicemos su código. ¿Funciona? ¿Cómo están las clases? ¿Con cuantos tipos de actores puede funcionar el espectáculo que estamos modelando? ¿Qué tengo que hacer para variar el tipo de actor? Aplicaciones fuertemente acopladas
Bajamos ahora el piloto 2.0. ¿Qué hemos mejorado? ¿Están las clases completamente desacopladas por el mero hecho de utilizar una interfaz? Taller práctico Completar el modelo para que incorpore la clase es.uniovi.si.factoria.Factoria que: ,[object Object]
sea un singleton
tenga un método ObjectgetService(String) que cuando reciba “Malabarista” devuelva una instancia de la clase Malabarista.(Resuelto en piloto 3.0) Refactorizando…
El BeanFactoryesunaimplementación del patrónfactoríaquepermitecrear beans declarándolos en un ficheros XML cuyaraizes la etiqueta <beans> El XML contieneuno o máselementos de tipo <bean> Atributoid (o nombre) paraidentificar el bean Atributoclass queespecifica el nombrecualificadocompleto de la clasequeimplementará el bean bautizado con id El contenedorBeanFactory
Pordefecto, los beans son tratadoscomosingletons (Dessign patterns, GoF’94),aunqueexistenotrosposiblespatrones de comportamiento. Ejemplo: El contenedorBeanFactory The bean’s fully- qualified classname The bean’s ID <beans>   <bean id=“widgetService”       class=“com.zabada.base.WidgetService”> </bean> </beans>
Para utilizarlo: BeanFactoryfactory = new XmlBeanFactory(<documento xml>); Factory.getBean(<identificador del bean>); El documento XML debe ser encapsuladoporalguna de lassiguientesclases wrapper. El contenedor BeanFactory
El documento XML declara los beans, asociándoles el identificador por el cual van a ser referenciados. <?xmlversion="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="actor" class="es.uniovi.si.Malabarista"/> </beans> El contenedor BeanFactory
Descargar piloto 4.0 y examinar el código fuente. Extender ésta versión del piloto para que la clase Show: Implemente un interfaz evento  que contenga su método de comienzo. Sea también creada por medio de la factoría BeanFactory, bajo el id de evento. (Resuelto en piloto 5.0) Taller práctico
El ciclo de vida con BeanFactory
El ciclo de vida con BeanFactory
A partir del piloto 5.0,  Definir un constructor público en la clase Malabarista que inicialice el número de objetos con los que hace los malabarismos. Modificar el bean.xml para que reciba 15 como parámetro de constructor al crear el bean. Probarlo Una vez comprobado, sobrecargamos el constructor con otro que reciba una cadena de texto y la muestre por pantalla. ¿Qué sucede? Añadir la etiqueta type para forzar a que se dispare el constructor que nos interesa. (resuelto en piloto 6.0) Taller práctico
Es el segundo tipo de inyección de dependencias posible. En lugar de pasarle la información por medio del método constructor, le decimos a Spring que le haga llegar la propiedad en el bean.xml Para ello debemos: Tener un método set para la propiedad Añadir una etiqueta property anidada a la definición del bean en el bean.xml <property name ="numeroObjetos" value="15"/> Inyección de parámetros por métodos setter
Además de valores sencillos, es posible inyectar una referencia a otro bean dado de alta en el contenedor. Ejemplo: <bean name=“widgetService” class=“com.zabada.base. WidgetServiceImpl”>   <property name=“widgetDAO”> <ref bean=“myWidgetDAO”/>   </property> </bean> Esto implica que la clase WidgetServiceImpldeberátener un métodosetWidgetDAO(WidgetServiceImpl ref) Inyección de referencias de objetos
Modificar el piloto para que la clase Show reciba como dependencia la instancia de la clases Malabarista en su propiedad actor. (Resuelto en piloto 7.0) Taller práctico
Es una extensión del BeanFactory (hereda de él) Permite más opciones: Incorpora mecanismos para la externalización de cadenas de texto e internacionalización (i18n) Unifica la carga de recursos, como las imágenes. Permite implementar un modelo de paso de mensajes mediante eventos a los beans, declarándolos como listeners del evento. Por lo general, se usa éste en lugar del BeanFactory, a no ser que estemos en entornos de recursos restringidos (dispositivos móviles o similares). El Contenedor ApplicationContext
Hay tres implementaciones del contenedor: Ejemplo: ApplicationContextcontext = new FileSystemXmlApplicationContext("c:/foo.xml"); El Contenedor ApplicationContext
El ciclo de vida con ApplicationContext
Descargar la versión 8.0 del piloto y examinar el código fuente. Ejecutarlo para comprobar que funciona correctamente. Taller práctico
Vamos a extender el piloto 8.0 de forma que: Aparezca una interfaz Instrumento con el método toca() que devuelve un String. Aparezca una clase Saxofon que implemente la interfaz Instrumento y suene “tuuuuttuuuuututuuuuutuuuu” Aparezca un nuevo actor de tipo Instrumentista tal que: Reciba por setter: Nombre El instrumento que toca Al actuar, muestre un mensaje diciendo que “fulanito hace …” con el sonido que haga el instrumento que esté tocando Damos de alta un nuevo beankenny, que se llame Kenny G , que toque el saxofón y hacemos que sea él el que actúe en el Show. Resuelto en piloto 9.0 Taller práctico – Juntándolo todo
Supuesto: Contratamos a otro saxofonista para el Show: <bean id="kenny" class="com.springinaction.springidol.Instrumentalist"> <propertyname=“nombre“ value=“juan”/> <propertyname="instrument"> <refbean="saxofon"/> 	</property> </bean> Pero…: A Kenny G (que “ye” muy fino) no le gusta compartir el saxofón ¿Cuántas instancias se crean del instrumento? Problema
Inspirados en las innerclassesde Java (Clases que de definen dentro de otras clases) Los innerbeans son beans que se definen dentro de otros beans, y cuyo ámbito se reduce al bean contenedor.  El bean contenido sólo será accesible por el que lo contiene: <propertyname="instrument"> <beanclass="org.springinaction.springidol.Saxophone" /> </property> (Ver ejemplo en piloto 10.0) InnerBeans
Hasta ahora hemos visto como utilizar Spring para configurar propiedades simples, de un solo valor o referencia. Pero… ¿Cómo hacerlo cuando tratamos con colecciones? Spring permite trabajar con cuatro tipos de colecciones. Cableado de colecciones
Si quisiéramos que en Show participasen kennyy el beanactor. Modificaremos la clase Show para que: En lugar de tener un atributo de tipo actor, lo tenga de tipo Collection<Actor>, con su correspondiente método setActores(…) Al comenzar el show, haga actuar a todos los actores del espectáculo que encuentre en la colección. for ( Actor actor:actores ){ actor.actua(); 		} Extendemos el beans.xml para anidar a los dos actores <propertyname="actores"> 		<list> 			<refbean…/> 		… 		</list> Resuelto en piloto 11.0 Cableado de colecciones
A partir del piloto 10, completarlo para que entre el malabarista y el saxofonista, actúe un hombre orquesta que toque el saxofón, la armónica y la guitarra. La armónica es suya y no la comparte, pero la guitarra es de la organización del show. Usaremos por convenio los nombres: Clase Guitarra. Clase Armonica Clase HombreOrquesta Clase  Hombre orquesta: Benja (Resuelto en piloto 11.0) Taller práctico: Repasando
Para “cablear” un Map, El objeto se tiene que esperar que le pasen como parámetro una instancia de la clase Map. PublicvoidsetInstrumentos(Map <String,Instrumento>)… El beans.xml debe enlazar el mapa con el parámetro instrumentos. <map> <entrykey="la guitarra" value-ref="fender" /> … Cableado de Mapas
Extender piloto 11.0 para que en lugar de pasar directamente las referencias a los beans que toca el Hombre Orquesta, le pasemos un mapa con el nombre que le queramos dar al instrumento, de forma que el mensaje al tocarlo sea… “El hombre orquesta toca la guitarra: rrriaaannnriiiaaaannnriiiiaaaannnnnnnn” Resuelto en piloto 12 Taller práctico
Modificar el piloto 12 para que: A cada actor pueda asignársele un nombre artístico cada vez que se enlace al show La salida una vez resuelto, será algo como: Presentamos a Tony Malabares Haciendo malabarismos con 15 objetos Presentamos a El Increible hombre orquesta El hombre orquesta toca la guitarra:rrriaaannnriiiaaaannnriiiiaaaannnnnnnn El hombre orquesta toca la armónica:tui tui tuiiiiiituiiiiiii Presentamos a Kenny G! Kenny G hace ttuuuuuutuuuutuuuuututuuuuuuuu Resuelto en piloto 13 Taller práctico
Hemos visto como “cablear” beans Con el elemento <constructor-arg> Con el elemento <property> Problema: En una aplicación complicada, esta práctica puede degenerar en un XML desmesurado e inmanejable. Alternativa: En lugar de definir explícitamente las relaciones entre beans, podemos dejar que Spring decida como debe cablearlos, mediante la propiedad autowire del elemento <bean> Auto-Cableado en Spring(Autowire)
Tipos de autocableado: Auto-Cableado en Spring(Autowire)
Todo en Spring tiene un nombre. <bean id="kenny" class="es.uniovi.si.Instrumentista"> 	<property name="nombre" value="Kenny G"/> 	<propertyname="instrumento"> 		<beanclass="es.uniovi.si.Saxofon"/> 	</property> </bean> Si queremos simplificar el XML: <bean id=“instrumento” class="es.uniovi.si.Saxofon"/> … <bean id="kenny" class="es.uniovi.si.Instrumentista“ autowire=“byName”> 	<property name="nombre" value="Kenny G"/> </bean> Lo cambiamos y lo probamos. ¿Funciona? (Resuelto en piloto 14.0) AutowirebyName
Similar a byName, salvo que la búsqueda la realiza por tipo, y no por nombre Por cada beanautocableado por tipo, Introspecciona las propiedades del bean Por cada setXXX no cableado explícitamente en el beans.xml,  busca un bean declarado que coincida en tipo con la propiedad, y si lo encuentra, lo cablea. Probamos: Partiendo del piloto 14.0, cambiar el autowire a byType. ¿Funciona? ¿Qué podemos hacer para arreglarlo? (Resuelto en piloto 15.0) AutowirebyType
Útil cuando utilizamos inyección de dependencias en el constructor. Si declaramos un beanautocableable por constructor: Spring busca por instrospección los constructores del bean Por cada uno, trata de buscar candidatos para satisfacer los tipos de sus parámetros entre los beans declarados en el beans.xml Si los encuentra, invoca el constructor. En caso de ambigüedad, dispara una excepción igual que cuando usamos byType Autowire por constructor
Nos permite delegar en el contenedor la decisión de qué bean debe ser cableado con otro, y de qué forma. <bean id="duke" class="com.springinaction.springidol.PoeticJuggler" autowire="autodetect" /> Para este ejemplo, Spring tratará de autocablear el bean por constructor, y en caso de no tener éxito, lo intentará por tipo. Autodetección de autowire
Si vamos a adoptar una política común de autocableado para todos los beans, podemos declararla a nivel de contenedor: <beansdefault-autowire="byName"> … </beans> Esta propiedad se puede sobrescribir a nivel de bean individual. Autocableado por defecto
Hasta ahora hemos usado la creación básica de beans, asumiendo que Spring crea una única instancia de cada uno. Existen más opciones para gestionar la instanciación de beans: Control del número de instancias creadas Singleton Una por request Una por petición Creación mediante factoría Incialización y destrucción controlada del bean Control del ciclo de vida del Bean
Por defecto, todos son singleton Problema: en determinados contextos, no podemos/queremos usar singletons. Utilizando el atributo scope del elemento bean determinamos su ciclo de vida: Control del ciclo de vida del BeanControl del ámbito (scope) del bean
Si queremos definir un bean como prototype: <bean id=<identificador>  class=<nombre de la clase> scope={prototype 			|singleton 			|request 			|session 			|global-session/> Uso del atributo scope
Modificar la versión 15 del piloto para que: El bean instrumento se instancie una vez por cada bean que lo utilice El Hombre Orquesta lo añada a su colección de instrumentos Junto con el “sonido” del saxofón, se muestre el valor de la referencia del objeto que lo identifica unívocamente en la JVM. Si ahora quitamos el scope… ¿Hay diferencia? (Resuelto en piloto 16.0) Taller práctico
Normalmente creamos las clases con su constructor público, pero por distintos motivos (código heredad, librerías de terceras partes, etc.), es posible que el bean que queremos “cablear” deba ser creado a partir de un factorymethod Ejemplo:  Queremos incorporar a modelo del Show un escenario que tenemos ya implementado de otra parte del sistema. Como es único, viene implementado como singlenton. Creación de beans desde factorías
Para la instanciación de este tipo de objetos, el elemento bean permite especificar el factory-method que debe invocar el contenedor para obtener una instancia del bean. <bean id=“<identificador>" class=“<nombre de la clase>" factory-method=“<método que retorna la instancia>" /> Creación de beans desde factorías
A partir del piloto 16.0: Crear una clase Escenario que implemente el patrón singleton, y llamamos al método de creación de instancia getInstancia(). Sobrescribir su método toString para que retorne “Escenario Central”. Modificar la aplicación para que el Show, antes de comenzar la actuación, obtenga una referencia al escenario y muestre por pantalla: Bienvenidos al Escenario Central (Resuelto en trabajo 17.0) Taller práctico
Es posible que un determinado bean requiera hacer operaciones de inicialización antes de poder realizar su tarea, o bien liberar recursos –conexiones a bbdd, cierre ficheros, etc- antes de su destrucción. Los atributos: init-method destroy-method nos permiten decirle al contenedor qué dos métodos queremos que realicen estas tareas de inicialización y destrucción. Al igual que con autowire, se pueden especificar los nombres de los métodos constructor y destructor a nivel de contenedor con default-init-methody default-destroy-method. Inicialización y destrucción de beans
A partir de trabajo 17.0: Implementar en el saxofón y en la armónica un método afinar y otro limpiar que publiquen sendos mensajes por la consola. Hacer que ambos se disparen como método de inicialización y método de destrucción. Probarlo. ¿Funciona? ¿Y si ahora lo pongo por defecto para todos los beans? <beans 	default-init-method="afinar" 	default-destroy-method="limpiar"> Taller práctico
Modificar y extender la clase Escenario para que tenga los métidos abrirTelon cerrarTelon Que impriman sendos mensajes y que sea invocado al inicializar y al destruir la clase.  Taller práctico
A partir del ejemplo anterior una vez terminado, probar a forzar a que la clase Instrumentista implemente las interfaces InitializingBean DisposableBean ¿Qué ocurre? Hacer lo necesario para que sea compilable y ejecutarlo. Resuelto en piloto 18.0 Inicialización por I.D. por interfaces
Modificar la clase Escenario de nuevo para que la inicialización y destrucción se realicen ahora por usando los dos interfaces: InitializingBean DisposableBean Taller práctico
Cableado avanzado de beans
Hasta ahora hemos declarado los beans de forma individual, estableciendo las propiedades de cada uno una a una de forma específica. Problema: Puede degenerar en ficheros de configuración muy extensos y poco tratables. Ejemplo: Tenemos muchos beans de un determinado tipo que comparten características ->Tenemos que definir la misma característica en todos ellos. En una orquesta, todos los instrumentistas tocan la misma canción Herencia
Al igual que en la POO, es posible definir relaciones padre-hijo entre los beans declarados en un contenedor. Un bean que extiende la declaración de otro bean se define como sub-bean del segundo. Dos atributos específicos para esto: Parent: Declara de qué bean hereda el que estamos declarando Abstract: Declara el bean como abstracto, y por lo tanto, no instanciable. Herencia
<bean id=“<nombre padre>" class=“<clase del padre>" abstract="true"> 	<propertyname=“<propiedad común>" ref=“<refbean a heredar>"/> </bean> <bean id=”<hombre hijo 1>" parent=”<nombre padre>"> <property name=“<otrapropiedad>" value=“<valor 1>"/> </bean> <bean id=”<hombre hijo 2>" parent=”<nombre padre>"> <property name=“<otrapropiedad>" value=“<valor 2>"/> </bean> Ejemplo
Modificar el piloto a partir de su versión 18 para que: Aparezca un bean Saxofonista que: Sea abstracto Esté ligado al Saxofón En el show participe un nuevo saxofonista con id=“bill” y nombre=“Bill Clinton”. Será presentado como “El presidente Clinton!”. Resuelto en trabajo 19.0 Taller práctico
Extender ahora el piloto 19.0 para que: Tanto los instrumentistas como los hombres orquesta tengan un atributo de tipo String que se llame tema. Poner a todos los implicados de acuerdo para que toquen “Paquito el Chocolatero” ... ¿Se repite configuración? ¿Debemos ligar el atributo tema a la clase Actor?  ¿Y el malabarista?  ¿Creamos una nueva clase intermedia? Taller práctico - repaso
En determinados contextos, puede que necesitemos compartir valores de propiedades entre beans de diferentes clases. Spring permite hacer esto declarando un bean abstracto sin especificar su clase, y forzando a los hijos a que lo extiendan. <bean id=“<bean base>" abstract="true"> <property name=“<nombrepropiedadcompartida>" value=“<valor de la propriedad>" /> </bean> Abstracción de propiedades comunes
Definir un bean abstracto Interprete que defina el valor de la propierdad tema para que toque “Paquito el chocolatero” y configurar los bean “Hombre Orquesta” y “Saxofonista” para que hereden dicha propiedad del intérprete. (Resuelto en piloto 20.0) Taller práctico
Habitual el lenguajes dinámicos como Ruby. Consiste en añadir nuevos métodos a una clase ya compilada, o modificar la definición de alguno ya existente. En Java y otros LOO “clásicos” no se puede hacer esto, son “poco flexibles” Spring permite “simular” la inyección de métodos en los beans que tenga declarados en el contenedor. Dos tipos: Remplazo de métodos Inyección de Getter Inyección de métodos
Spring interceptará las invocaciones que se realicen al método sustituido para inyectar en medio la nueva implementación del mismo Es necesario implementar un objeto que cumpla la interfaz MethodReplacer public class <NombreClase> implements MethodReplacer { public Object reimplement(Object target, Method method, Object[] args) throwsThrowable{ ... } Remplazo básico de método
Una vez dado de alta, sustituimos el método en el beans.xml <bean id="<bean sustituto>"  class=“<clase methodreplacer>"/> <bean ...> 	... 	<replaced-methodname=“<método a sustituir>” replacer=“<bean sustituto>"/> </bean> Remplazo básico de método
Descargar piloto 20.0 (importante partir de éste, incluye nuevas referencias a jars) y extenderlo para sustituir el sonido del saxofón. Para ello: Implementar una clase Sintentizador que modifique el sonido del saxofón, retornando una nueva cadena de sonido. Darlo de alta en el beans.xml como sintentizador y utilizar el elemento replaced-method en el beansinstrumento para sobrescribir el método toca. ¿Funciona? ¿Qué clase está realmente ejecutándose? Añadir a la nueva cadena de sonido la referencia al objeto que se ejectura (Wrapper). Resuelto en Versión 21.0 (Ojo!!! Sólo funciona si obtenemos el objeto a través de Spring! Taller práctico
Si el método que queremos inyectar es un método getter para que retorne un bean contenido en el contenedor, podemos directamente obviar su implementación y decirle a Spring que intercepte la petición. <bean id=“<nombre bean>” class=“<clase del bean>”> 	… <lookup-methodname=“<nombre getter>" bean=“<bean a retornar>"/> </bean> Inyección de Getter
Vamos a darle “el cambiazo” a kenny, sustituyéndole el saxofón por la guitarra fender. Para ello, Modificamos el método actua de la clase Instrumentista para que cuando acceda al instrumento lo haga a través de su método getter. Transformamos el innerbeanfenderen uno normal para que pueda ser accedido desde otros beans. Sobrescribimos el getter de kenny para que getInstrumento retorne el beanfender. (Resuelto en piloto 21.0) ¿Qué clase está realmente implementando el método actúa? Taller práctico
Las propiedades vistas hasta ahora son simples, pero normalmente nos enfrentamos a estructuras más complejas Ej: Reconocer y procesar una URL: http://www.xmethods.net/sd/BabelFishService.wsdl Spring, puede convertir automáticamente el texto anterior en un objeto de tipo URL. ¿Cómo lo hace? Mediante un property editor  basado en la especificación de Java Beans. Registrando editores de propiedades personalizados
Interfaz java.beans.PropertyEditor Permite especificar como se deben mapear datos de tipo String en tipos no String. Fuerza a tener dos métodos: getAsText()- Devuelve la representación en forma de String del valor setAsText(String) – Transforma el String que recibe en el formato correspondiente. Si se trata de dar un valor de tipo String a una propiedad que no lo es, se disparará el método setAsText() para realizar la conversión. getAsText() se usará para representar el valor. El interfaz PropertyEditor
Spring incorpora varios editores de propiedades a medida, basados en la clase PropertyEditorSupport. PropertyEditors de Spring
Podemos desarrollar nuestro propio editor de propiedades personalizado para nuestra aplicación. Ejemplo (A partir de piloto 22.00): Vamos a añadir información de contacto a todos los instrumentistas. Creamos una clase Telefono con los atributos  codigoPais numero extension Y sus correspondientes getters y constructor parametrizado. Desarrollo de PropertyEditors a medida
Añadimos una instancia de la clase Telefono como propiedad de la clase Instrumentista Y ahora configuraremos el contenedor para asignarle un teléfono a Kenny G. <bean id="telefono1" class="es.uniovi.si.Telefono"> 	<constructor-argvalue="0034"/> 	<constructor-argvalue="985105094"/> 	<constructor-argvalue="00"/> </bean> <bean id="kenny" parent="Saxofonista"> 	<property name="nombre" value="Kenny G"/> 	<propertyname="telefono" ref="telefono1"/> 	<lookup-methodname="getInstrumento" bean="fender"/> </bean> ¿Funciona? Sí, pero es tedioso y poco práctico Desarrollo de PropertyEditors a medida
Alternativa: Creamos nuestro propio PropertyEditor: public class TelefonoPropertyEditor extends PropertyEditorSupport { publicvoidsetAsText(String texto){ Stringstripped = stripNonNumeric(texto); StringcodigoPais = stripped.substring(0,3); String numero = stripped.substring(3,12); Stringextension = stripped.substring(12); Telefonotelefono = new Telefono(codigoPais, numero, extension); setValue(telefono);} privateStringstripNonNumeric(String original) { StringBufferallNumeric = new StringBuffer(); for(int i=0; i<original.length(); i++) { char c = original.charAt(i); if(Character.isDigit(c)) { allNumeric.append(c); 		} 	} returnallNumeric.toString();} } Desarrollo de PropertyEditors a medida
Ahora sólo nos falta decirle a Spring cuando y como aplicar el nuevo property editor, por medio delCustomEditorConfigurer CustomEditorConfigurer es un BeanPostProcessor que carga los editores de propiedades en la BeanFactory. Para ello: <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"> 	<propertyname="customEditors"> 	<map> 		<entrykey="es.uniovi.si.Telefono"> 			<bean id="TelefonoEditor" class="es.uniovi.si.TelefonoPropertyEditor"> 			</bean> 		</entry> 	</map> 	</property> </bean> Desarrollo de PropertyEditors a medida
Ahora ya podemos asignárselo directamente a kenny <bean id="kenny" parent="Saxofonista"> 	<property name="nombre" value="Kenny G" /> 	<property name="telefono" value="0034-650423932-00" /> 	<lookup-methodname="getInstrumento" bean="fender" /> </bean> (Resuelto en piloto 23.0) Desarrollo de PropertyEditors a medida
Creamos ahora un propertyEditor para el email: Creamos una clase email con dos propiedades: usuario y servidor. Hacemos sus accessors y su constructor parametrizado Añadimos Email como propiedad de instrumentista Creamos el properyeditor para convertir el email email.setUsuario(texto.substring(0,texto.indexOf('@'))); email.setServidor(texto.substring( texto.indexOf('@')+1,texto.length()));	 Añadimos el nuevo email property editor al map del CustomEditorConfigurer Le asignamos bill.clinton@whitehouse.org al beanbill. Resuelto en 23.5 Taller práctico
La mayoría de los beans que manejará el contenedor son tratados de la misma forma – la vista hasta ahora. Para determinadas tareas, Spring permite especificar que determinados beans sean tratados de manera especial. Para marcar aquellos beans que deben ser tratados como tales, nos serviremos de la inyección de dependencias por interfaces. Los beans “especiales de Spring
Mediante estos, podemos: Tomar parte en la creación de los beans y en el ciclo de vida de la factoría mediante posprocesamiento. Cargar ficheros de configuración externos –en ficheros property Cargar mensajes de texto, como base para la internacionalización. Ligar el bean a la recepción de eventos. Los beans “especiales de Spring
Permiten programar ciertas tareas que se dispararán antes y después de la inicialización de los beans del contenedor El bean de PostProcesamiento se configura POR CONTENEDOR Para esto, tenemos que: Crear un bean que implemente la interfaz BeanPostProcessor Darlo de alta en el contenedor.  Beans de posprocesamiento
El bean debe implementar la interfaz BeanPostProcessor: public interface BeanPostProcessor { ObjectpostProcessBeforeInitialization( Object bean, String name) throws BeansException; ObjectpostProcessAfterInitialization( Object bean, String name) throws BeansException; } Creación del BeanPostProcessor
Tenemos dos alternativas: Si trabajamos con BeanFactory: BeanPostProcessorfuddifier = new Fuddifier(); factory.addBeanPostProcessor(fuddifier); Si trabajamos con ApplicationContext: <beanclass=“<nombre de la clase postprocesadora>"/> En el segundo caso, basta con esto. El propio contenedor se dará cuenta de que el bean instanciado implementa la interfaz BeanPostProcessor y lo incluirá como tal en el ciclo de vida de los beans corrientes. Configurar el postprocesador
Queremos desarrollar un postprocesador que “se chive” de quienes están actuando en el Show, de forma que para todo aquel bean que tenga nombre (y por lo tanto, método getNombre()), se genere un mensaje por pantalla notificando que “fulanito” ha actuado. Para ello, habrá que  desarrollar el postprocesador darlo de alta en el contenedor Ejemplo: Con hacienda hemos topado
publicclassHaciendaPostProcessorimplementsBeanPostProcessor { 	@Override publicObjectpostProcessAfterInitialization(Objectbean, String arg1) throwsBeansException { 			try { Methodmethod= bean.getClass().getMethod("getNombre"); if ( method!=null ){ String nombre = (String) method.invoke(bean, null); System.out.println("REGISTRADA ACTUACIÓN DE "+nombre); 				} 			} 			catch (NoSuchMethodException e) { 				//No hacemos nada. 			} catch (Exceptionee) { ee.printStackTrace();		 			} returnbean; 	} 	@Override publicObjectpostProcessBeforeInitialization(Objectbean, String arg1) throwsBeansException { returnbean; 	} } HaciendaPostProcessor
Y lo damos de alta en el contenedor <beanclass="es.uniovi.si.HaciendaPostProcessor"/> Resuelto en Piloto 24.0 Taller práctico Descargar el piloto 24.0 Importarlo en Eclipse Examinar el código fuente HaciendaPostProcessor
Ahora llega la SGAE! Extender el piloto par añadir un nuevo beanpostprocesadorSGAEPostProcessor que saque por pantalla todos aquellos temas que se toquen en el Show, intentando acceder al método getTema de cada bean declarado en el mismo. (Será necesario añadir el método getTema() a los que ya cuentan con setTema()) (Resuelto en piloto 25.0). Taller práctico: De mal en peor…
Similar al BeanPostProcessor, el BeanFactoryPostProcessor permite realizar tareas de postprocesamiento sobre todo el contenedor de Spring. public interface BeanFactoryPostProcessor { voidpostProcessBeanFactory( ConfigurableListableBeanFactorybeanFactory) throwsBeansException; } El método postProcessBeanFactoryes invocado por Spring una vez las definiciones hayan sido cargadas, pero antes de que los beans sean instanciados. Postprocesamiento de la factoría
Ejemplo: Para saber cuantos beans han sido declarados en el beans.xml public class BeanCounter implements BeanFactoryPostProcessor { privateLoggerLOGGER = Logger.getLogger(BeanCounter.class); publicvoidpostProcessBeanFactory( ConfigurableListableBeanFactoryfactory) throwsBeansException { LOGGER.debug("BEAN COUNT: " + factory.getBeanDefinitionCount()); 		} } Para darlo de alta en el contenedor. <bean id="beanCounter”class="com.spring.BeanCounter"/> Postprocesamiento de la factoría
Es posible configurar los beans mediante el beans.xml y el elemento <property>.  Sin embargo, no conviene mezclar el cableado de beans con la configuración específica de nuestra aplicación. Spring proporciona el objeto PropertyPlaceholderConfigurer si trabajamos con el ApplicationContext para esto. <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 	<property name="location" value=“<fichero.properties>" /> </bean> Externalizando la configuración de los beans
Puede que necesitemos modular la configuración en diferentes ficheros de propiedades:  <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  <propertyname="locations"> 		<list> 			<value>jdbc.properties</value> 			<value>security.properties</value> 			<value>application.properties</value> 		</list>  </bean> Externalizando la configuración de los beans
Ahora podemos recuperar los valores de configuración referenciándolos por medio de variables en lugar de tenerlos “hardcodeados” en el beans.xml <bean id="dataSource” class= "org.springframework.jdbc.datasource.DriverManagerDataSource"> 	<propertyname="url” value="${database.url}" /> 	<propertyname="driverClassName” value="${database.driver}" /> 	<propertyname="username” value="${database.user}" /> 	<propertyname="password” value="${database.password}" /> </bean> Externalizando la configuración de los beans
Externalizando la configuración de los beans
Extender el piloto 25.0 para que tome los siguientes datos del fichero Configuracion.properties: numero.malabares=25 tema=19 días y 500 noches (Resuelto en piloto 26.0) Taller práctico
En determinados casos, los beans necesitarán tener acceso a objetos de Spring, como el ApplicationContext. Esto se resuelve mediante inyección de dependencias por interfaz. Hay tres posibles interfaces que dan acceso a sendos objetos: BeanNameAware BeanFactoryAware ApplicationContextAware Beansatentos (Aware)
Implementando la interfaz BeanNameAware le estoy diciendo al contenedor que queremos que nos inyecte el identificador con el que el bean ha sido declarado en el beans.xml public interface BeanNameAware { voidsetBeanName(Stringname); 	} Cuando cada bean sea cagado, el contenedor comprobará por introspección si implementa esta interfaz ( isInstanceOf(…)).  En tal caso, invocará su método setBeanName(…) pasándole como parámetro el identificador del bean. ¿Quién Soy?: BeanNameAware
De la misma forma, accedemos a la factoría y al contexto: publicclassStudentServiceImplimplementsStudentService, ApplicationContextAware { privateApplicationContextcontext; publicvoidsetApplicationContext(ApplicationContextcontext) { this.context = context; 	} 	… } ¿De dónde vengo?: BeanFactoryAware & ApplicationContextAware
Modificar el piloto 26.0 par que: La clase Malabarista reciba y almacene Contexto La factoría Su nombre Forzar además a que cuando reciba su nombre, muestre un mensaje diciendo:	 	“Hola, me llamo actor” (Resuelto en piloto 27.0) Taller práctico
La inyección de dependencias no es la única forma de interacción entre beans en Spring. La otra alternativa es basarse en el modelo de eventos de los JavaBeans. Un beanpublicador dispara un evento que será recibido por todos aquellos que estén registrados como escuchadores.  El publicado y los escuchadores (listeners) no se conocen entre sí, están desacoplados. Gestión de Eventos en Spring
Es Spring un bean puede ser Publisher Listener Ambos dos. Gestión de Eventos en Spring
Un evento para poder ser gestionado por Spring debe extender la clase ApplicationEvent. publicclassCourseFullEventextendsApplicationEvent { privateCoursecourse; publicCourseFullEvent(Objectsource, Coursecourse) { super(source); this.course = course; 	} publicCoursegetCourse() { returncourse; 	} } Creación de eventos
Una vez creado… ¿Cómo lo publicamos? El objeto ApplicationContext tiene el método publishEvent(), que nos permite publicar instancias de la clase ApplicationEvent. Todo aquel beanApplicationListener registrado en el contenedor recibirá el evento mediante una llamada a su método onApplicationEvent() ApplicationContextcontext = …; Coursecourse = …; context.publishEvent(new CourseFullEvent(this, course)); Problema: Necesitamos hacer que un bean sea capa de procesar eventos.  ¿Cómo se hace eso? Publicación de Eventos
Para que un bean dado de alta en el contenedor reciba eventos que extiendan la clase ApplicationEvent, deberá implementar la Interfaz ApplicationListener Public interface ApplicationListener { publicvoidonApplicationEvent(ApplicationEventevent); } El contenedor detecta que es listener de los eventos y lo añade automáticamente a la suscripción. Ser Listener
Extender el piloto 27 para que: Aparezca una clase Representante y un bean de su tipo declarado en el contendor. Aparezca un evento PaseEvent con un método getActor() que retorne la instancia de Actor que actúa en el Show. El bean Show lance un evento PaseEvent por cada actor que actúe para que el Representante lo escuche y tome nota de cuanto debe facturar al gestor. (Resuelto en el piloto 28.0) Taller práctico
El show va a ser retransmitido por televisión, y por lo tanto, es necesario avisar al técnico de control para que cuando termine una actuación importante, pase a publicidad, y cuando comience la siguiente importante, retome la conexión con el escenario. La tele sólo se interesa por las grandes personalidades como Kenny G y Bill Clinton, pero para mantener al público viendo los anuncios, los ponemos al comienzo y fin de espectáculo. Para modelar esto, vamos a necesitar crear dos tipos de eventos diferentes que representen el comienzo y el final de una actuación. En el primero además enviaremos el actor participa en el mismo. Taller práctico
Tendremos que: Creamos dos nuevos eventos: ComienzoVIPEvent – con una propiedad Actor FinVIPEvent Modificar la clase Show para que cuando comiencen bill o kenny se dispare el correspondiente evento, así como cuando finalicen. Implementar TecnicoTelevision y dar de alta al bean “urdazi” como tal. Tiene que ser capaz de escuchar eventos de tipo ApplicationEvent, y publicar los mensajes de inicio y fin de la retransmisión, dependiendo del evento que le llegue. Resuelto en piloto 28.5 Taller práctico
Spring AOP Programación Orientada a Aspectos
Definición de POA Fue presentada en público por Gregor Kickzales y su equipo de investigación de Palo Alto Research Center en 1996. Paradigma de programación relativamente reciente. De esta forma se consigue: Razonar mejor sobre los conceptos. Eliminar la dispersión del código. Implementaciones resultan más comprensibles, adaptables y reusables.
Definición de Aspecto “ Un aspecto es una unidad modular que se disemina por la estructura de otras unidades funcionales. Los aspectos existen tanto en la etapa de diseño como en la de implementación. Un aspecto de diseño es una unidad modular del diseño que se entremezcla en la estructura de otras partes del diseño. Un aspecto de programa o de código es una unidad modular del programa que aparece en otras unidades modulares del programa (G. Kiczales) ”
Definición de Aspecto Los aspectos son la unidad básica de la POA, y pueden definirse como las partes de una aplicación que describen las cuestiones claves relacionadas con la semántica esencial o el rendimiento.  También pueden verse como los elementos que se diseminan por todo el código y que son difíciles de describir localmente con respecto a otros componentes. Ej.: patrones de acceso a memoria, sincronización de procesos concurrentes, manejo de errores, etc.
Estructura de un Programa OA
Estructura de un Programa OA Se muestra un programa como un todo formado por un conjunto de aspectos más un modelo de objetos. Con el modelo de objetos se objetos se recoge la funcionalidad de negocio. Los aspectos recogen características de rendimiento, infraestructura y otras no relacionadas con el modelo de negocio.
Objetivos Fundamentales de la POA Extraer y centralizar en un solo punto los "crosscuttingconcepts“  cada decisión se toma en un lugar concreto y no diseminada por la aplicación.  Minimizar las dependencias entre ellos  desacoplar los distintos elementos que intervienen en un programa.
Objetivos Fundamentales de la POA Idea principal es centralizar en un solo punto todos los aspectos comunes a las clases que forman el sistema software. Figura 1. Evolución de un sistema OO a uno OA
Ventajas de la POA Un código menos enmarañado, más natural y más reducido.  Mayor facilidad para razonar sobre los conceptos, ya que están separados y las dependencias entre ellos son mínimas.  Un código más fácil de depurar y más fácil de mantener.
Ventajas de la POA Se consigue que un conjunto grande de modificaciones en la definición de una materia tenga un impacto mínimo en las otras.  Se tiene un código más reusable y que se puede acoplar y desacoplar cuando sea necesario.
Programa Tradicional Vs. OA
Conceptos Básicos de POA Aspecto
Otros Conceptos de POA
Consideraciones Importantes La POA no rompe con las técnicas de programación orientadas a objetos sino que las complementa y extiende. El nuevo paradigma de la programación orientada a aspectos es soportado por los llamados lenguajes de aspectos, que proporcionan constructores para capturar los    elementos que se diseminan por todo el sistema.
Para tener un programa orientado a aspectos necesitamos definir los siguientes elementos: ,[object Object]
Uno o varios lenguajes de aspectos. El lenguaje de aspectos define la forma de los aspectos, por ejemplo, los aspectos de AspectJ se programan de forma muy parecida a las clases.
Un tejedor de aspectos. Fundamentos de la POA
Fundamentos de la POA ,[object Object]
Son los lugares del código en los que éste se puede aumentar con comportamientos adicionales. Estos comportamientos se especifican en los aspectos.,[object Object]
Estructura de una implementación en  los lenguajes tradicionales. Implementación en Lenguajes
Implementación en lenguajes Estructura de una implementación  en los lenguajes de aspectos.
Los aspectos son tejidos en los objetos objetivo en los puntos de enlazado especificados (joinpoints). Puede ser en tres momentos de la vida del objeto: Tiempo de compilación – El código fuente del objetivo es enriquecido con el código de los aspectos en los joinpoints, y luego compilado. Así trabaja AspectJ Durante la carga de clases – Los aspectos se enlazan en el momento de la carga de clases. Se requiere un ClassLoader especial.  En tiempo de ejecución – Aplicando el patrón Proxy, se intercepta la petición y se delega en los aspectos cuando se requiere. Spring AOP trabaja de esta forma. Tipos de enlazado (Weaving)
Los advices en Spring están escritos en Java Podemos usar IDEs corrientes Conocemos el lenguaje Los pointcuts se declaran en un fichero XML Estándar conocido. AspectJ requiere una sintaxis especial. Spring realiza el tejido de aspectos en tiempo de ejecución, sirviéndose del patrón Proxy. ¿Qué nos permite Spring AOP?Soporte de Spring
La ejecución el objeto “acosejado” por el aspecto es interceptada por un objeto Proxy que realiza las labores definidas en el pointcut. Los proxies serán creados por el ApplicationContext cuando carga los beans declarados en el contenedor. Dado que se crean en tiempo de ejecución, no se necesita ningún compilador específico para AOP con Spring. Funcionamiento de Spring AOP
Dos tipos: La clase aspectizada implementa un interfaz que contiene los métodos por los que se van a realizar los pointcuts Spring usa la java.lang.reflect.Proxy para generar automáticamente una nueva clase que implementa la ineterfaz, teje los aspectos e intercepta toda llamada a esos métodos de la interfaz. La clase es un POJO. Spring usa CGLIB para generar un proxy a medida en tiempo de compilación, extendiendo la clase objetivo (por lo que no podemos usar métodos final.) Tipos de intercepción
Spring implementa las interfaces de AOP Alliance: Acuerdo para promover un uso estandarizado de la AOP independientemente de la tecnología (Java) subyacente sobre la que se generen los aspectos. Un aspecto creado con estos interfaces es portable a otras plataformas AOP AOP Alliance Interfaces
Spring sólo soporta MethodJoinpoints Otras plataformas (AspectJ, Aspect JBOSS) soportan fieldjoinpoints, lo que permite aspectos más refinados. No obstante, si todos los accesos a atributos se realizan por medio de los métodos accessor, se pueden emular los efectos. Puntos de unión en Spring
Tipos de advices
Vamos a probar los aspectos extendiendo el Espectáculo que ya tenemos funcionando, haciendo que aparezca un nuevo actor: el público. Antes de nada, bajamos de la zona de descargas el jar de la CGLIB y lo añadimos en lib y al classpath del proyecto actual. Creamos una clase Audiencia con los siguientes métodos, y la declaramos como el beanaudiencia en el beans.xml: Mi primer aspecto
Ahora... ¿Quién invoca a la clase audiencia? El público no va dirigido ni por el actor de turno, ni por el propio espectáculo, sino que responden a situaciones automáticamente. Vamos a crear un aspecto para que dispare los métodos del bean audiencia antes y después de cada actuación de un actor. Mi primer aspecto
Creamos una nueva clase Java es.uniovi.si.aop.AudienciaAdvice, de forma que: Implemente: AfterReturningAdvice MethodBeforeAdvice ThrowsAdvice Tenga una propiedad audiencia para poder obtener una referencia a la misma por inyección. Implementamos los tres métodos, invocando a los métodos de audiencia que corresponda en cada contexto. Implementando el aspecto
Una vez creada la clase AudiencieAdvise, damos de alta el beanaudiencieAdvice inyectando la audiencia como propiedad. Ahora tenemos que definir el punto de corte. Con el punto de corte le diremos a Spring donde exactamente queremos aplicar el advice que hemos implementado. Spring permite utilizar varios tipos de puntos de corte. Implementando el aspecto
Objetivo: seleccionar los métodos sobre los que aplicar el advise. Solución: Aplicación de un patrón de expresiones regulares sobre la signatura de los métodos Spring incorpora dos clases que implementan estos puntos de corte: org.springframework.aop.support.Perl5RegexpMethodPointcut (Requiere Jakarta ORO) org.springframework.aop.support.JdkRegexpMethodPointcut (Usa el RegExp incorporado en Java 1.4) Declarando un punto de corte con expresiones regulares.
Para utilizar el punto de corte, primero tenemos que declararlo como bean en el contenedor: <bean id=“actuacionPointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut"> 	<property name="pattern" value=".*actua" /> </bean> Este patrón encaja con cualquier método que se llame actua. Declarando un punto de corte con expresiones regulares.
Ahora tenemos que asociar el punto de corte con el advice: <bean id="audienciaAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"> <property name="advice" ref="audienciaAdvice" /> <property name="pointcut" ref="actuacionPointcut" /> </bean> Con esto ya tenemos el aspecto completo implementado. Para que funcione, nos falta un último paso, la creación de los objetos proxy de los beans que queremos “aspectizar” Asociando pointcut y advice
Para todo bean “aconsejado” por un advisor, es necesario crear un proxy.  El proxy es el que realmente actuará cuando el advisor haga su trabajo, y por lo tanto, es el que realmente debemos “cablear”. Para crear un proxy para el kenny, por ejemplo: Creación de los Proxies
<bean id="kenny" class="org.springframework.aop.framework.ProxyFactoryBean"> 	<property name="target" ref="kennyTarget" /> 	<property name="interceptorNames" value="audienciaAdvisor" /> 	<propertyname="proxyInterfaces” value="es.uniovi.si.Actor" /> </bean> <bean id="kennyTarget" parent="Saxofonista"> 	<property name="nombre" value="Kenny G" /> 	<property name="telefono" value="0034-650423942-00" /> 	<lookup-methodname="getInstrumento" bean="fender" /> </bean> Creamos los proxies para el resto de los actores y ya podemos ejecutar la aplicación. (Resuelto en Piltoto 29.0) Creación del proxy para los beansaspectizados
Modificar el piloto 29.0 para que la guitarra dispare irremisiblemente una excepción de tipo Runtime() y comprobar que el público pide su devolución. (Resuelto en piloto 30.0) Taller práctico
La organización del espectáculo está preocupada por los controles de inmigración que la seguridad social está realizando sin previo aviso, así que decide poner un vigilante que, antes de cada actuación, le pida las credenciales a los artistas para dejarles trabajar o no. Tendremos que seguir los siguientes pasos... Taller práctico – El vigilante de seguridad
Añadir a Actor un método getCredenciales que retorne un boolean (indicando si las tiene o no). Creamos es.uniovi.si.VigilanteAdvise para que implemente BeforeAdvise, y lo damos de alta como vigilanteAdvise. Implementamos el método before para que muestre un mensaje indicando si el target (tercer parámetro del método) tiene o no credenciales. El punto de corte... Ya lo tenemos declarado! Será el mismo que para el ejemplo anterior Asociamos el nuevo advisor con el punto de corte mediante el pointcutadvisorvigilanteAdvisor. Finalmente, en el proxy, forzamos a que tenga en cuenta ambos interceptores: <property name="interceptorNames" value="audienciaAdvisor,vigilanteAdvisor" /> Resuelto en piloto 31.0 Taller práctico – El vigilante de seguridad
A partir del piloto 31.0, modificarlo para que: el malabarista no tenga credenciales El vigilante lance una excepción de tipo InmigranteIlegalExcepcion avisando de que no puede trabajar. Ejecutarlo ¿Qué ha ocurrido? ¿Dónde deberíamos capturar la excepción para que la aplicación siga funcionando?  Capturarla en el lugar adecuado y mostrar un mensaje de la organización explicando la cancelación de la actuación. (Resuelto en piloto 32.0) Taller práctico – Probando al vigilante
Poniéndolo en práctica
Vamos a comenzar la implementación de una infraestructura base basada en Spring para el desarrollo de aplicaciones.  Desarrollaremos el esqueleto de una aplicación modelo sirviéndonos de Spring para ahorrarnos código que solemos tener que implementar para cada aplicación. Aplicando Spring
Partir del último piloto manipulado y: Eliminar todas las clases menos la factoría Dejar el beans.xml sin ningún bean para poder empezar de cero. Vamos a partir de un entorno vacío sobre el cual trabajar. Implementar la clase Main con método main y método comienzo. El main obtendrá una referencia a sí mismo por medio de la factoría e invocará su método comienzo. Primer paso: Preparando el entorno
Queremos desarrollar un menú configurable que valga para cualquier aplicación de ventanas. Cada elemento del menú (MenuItem) contendrá una descripción (description) y uno o varios subelementos, que serán inyectados por Spring. Configurarlo para que de momento tenga la siguiente estructura: Desarrollando el menú
Desarrollo del menú Finalmente, implementar un método printMenu en la clase Main que pinte tabuladamente las diferentes opciones del menú invocando el toString() de muniItem. (Resuelto en piloto 40.0)
Vamos a aplicar el patrón command. Para ello: Implementaremos un interface es.uniovi.si.menu.MenuCommand que contenga un método execute. Prepararemos el MenuItem para que: Pueda recibir uno o varios Command por inyección, y los invoque en orden de inyección en un método run Creamos un comando (ejemplo, es.uniovi.si.comandos.AbrirCommand) para cada opción final del menú que de momento sólo mostrará un mensaje cuando se invoque, y los inyectamos en su correspondiente opción del menú. (Resuelto piloto 41.0) Inyectando lógica en el menú
Añadir a MenuItem una propuedadbooleanactive  SIN INICIALIZAR, y modificarlo para que si vale false, el ´nombre del menú aparezca entre * al llamar al toString(). Ej: *Abrir* Crear los eventos: es.uniovi.si.menu.event.AuthorizeMenuItemsEvent es.uniovi.si.menu.event.DenyMenuItemsEvent es.uniovi.si.menu.event.AuthorizeAllMenuItemsEvent es.uniovi.si.menu.event.DenyAllMenuItemsEvent 	de forma que los dos primeros contengan una colección con los ids (tal y como han sido asignados en el beans.xml) de los menús a activar o desactivar. Crear una clase MenuController, que implemente los métodos  autorizeMenuItems(…) denyMenuItems(…) authorizeAll() denyAll() 	de forma que se sirva de los eventos para activar o desactivar las opciones del menú que le soliciten cambiar. Las dos primeras podrán recibir uno o varios ids de tipo String. Lo instanciamos como el bean “menuController” y se lo inyectamos a Main Activando y desactivando menús
Configurar el menú para que por defecto, todos los menús estén activos (¿uno a uno?), y cambiar lo necesario para que el menú pegar aparezca desactivado. Para probarlo, modificar el método comienzo de Main para que: Pinte el menú Desactive el menú de cortar Pinte el menú Active todas las opciones Pinte el menú (Resuelto en piloto 42.0) Activando y desactivando menús

Más contenido relacionado

La actualidad más candente

Orm hibernate springframework
Orm hibernate springframeworkOrm hibernate springframework
Orm hibernate springframeworkVortexbird
 
Plataforma de programación Java
Plataforma de programación JavaPlataforma de programación Java
Plataforma de programación JavaAntonio Contreras
 
SpringFramework Overview
SpringFramework OverviewSpringFramework Overview
SpringFramework Overviewzerovirus23
 
Presentacion Spring Roo Java Mania
Presentacion Spring Roo Java ManiaPresentacion Spring Roo Java Mania
Presentacion Spring Roo Java ManiaJavier Onsurbe
 
Maven Divide tu código, pruébalo y vencerás
Maven Divide tu código, pruébalo y vencerásMaven Divide tu código, pruébalo y vencerás
Maven Divide tu código, pruébalo y vencerásCristian Romero Matesanz
 
Aplicaciones java. Presentacion Power Point
Aplicaciones java. Presentacion Power PointAplicaciones java. Presentacion Power Point
Aplicaciones java. Presentacion Power PointMariviMartinezM
 
Ionic2 01-introduccion
Ionic2 01-introduccionIonic2 01-introduccion
Ionic2 01-introduccionDavid Vaquero
 
Curso Java Avanzado 0 Conceptos Basicos
Curso Java Avanzado   0 Conceptos BasicosCurso Java Avanzado   0 Conceptos Basicos
Curso Java Avanzado 0 Conceptos BasicosEmilio Aviles Avila
 
PRIMERA PRESENTACION JAVA
PRIMERA PRESENTACION JAVAPRIMERA PRESENTACION JAVA
PRIMERA PRESENTACION JAVANoralma Yanez
 
Symfony2 Formacion y primeros pasos
Symfony2  Formacion y primeros pasosSymfony2  Formacion y primeros pasos
Symfony2 Formacion y primeros pasosSoni BM
 
Introducción a Java EE
Introducción a Java EEIntroducción a Java EE
Introducción a Java EEPaco Saucedo
 
Mi primer programa en Symfony2
Mi primer programa en Symfony2Mi primer programa en Symfony2
Mi primer programa en Symfony2César Hernández
 

La actualidad más candente (19)

Orm hibernate springframework
Orm hibernate springframeworkOrm hibernate springframework
Orm hibernate springframework
 
Herramientas Java
Herramientas JavaHerramientas Java
Herramientas Java
 
Plataforma de programación Java
Plataforma de programación JavaPlataforma de programación Java
Plataforma de programación Java
 
SpringFramework Overview
SpringFramework OverviewSpringFramework Overview
SpringFramework Overview
 
Spring mvc
Spring mvcSpring mvc
Spring mvc
 
Presentacion Spring Roo Java Mania
Presentacion Spring Roo Java ManiaPresentacion Spring Roo Java Mania
Presentacion Spring Roo Java Mania
 
Maven Divide tu código, pruébalo y vencerás
Maven Divide tu código, pruébalo y vencerásMaven Divide tu código, pruébalo y vencerás
Maven Divide tu código, pruébalo y vencerás
 
Curso Spring Roo Spring Data Jpa Maven
Curso Spring Roo Spring Data Jpa MavenCurso Spring Roo Spring Data Jpa Maven
Curso Spring Roo Spring Data Jpa Maven
 
Semana9 Vbr
Semana9 VbrSemana9 Vbr
Semana9 Vbr
 
Aplicaciones java. Presentacion Power Point
Aplicaciones java. Presentacion Power PointAplicaciones java. Presentacion Power Point
Aplicaciones java. Presentacion Power Point
 
Ionic2 01-introduccion
Ionic2 01-introduccionIonic2 01-introduccion
Ionic2 01-introduccion
 
Curso Java Avanzado 0 Conceptos Basicos
Curso Java Avanzado   0 Conceptos BasicosCurso Java Avanzado   0 Conceptos Basicos
Curso Java Avanzado 0 Conceptos Basicos
 
PRIMERA PRESENTACION JAVA
PRIMERA PRESENTACION JAVAPRIMERA PRESENTACION JAVA
PRIMERA PRESENTACION JAVA
 
Guia del trabajo con excepciones
Guia del trabajo con excepcionesGuia del trabajo con excepciones
Guia del trabajo con excepciones
 
Semana 1 Introducción a Java
Semana 1   Introducción a JavaSemana 1   Introducción a Java
Semana 1 Introducción a Java
 
Symfony2 Formacion y primeros pasos
Symfony2  Formacion y primeros pasosSymfony2  Formacion y primeros pasos
Symfony2 Formacion y primeros pasos
 
20001215 Programación de Servlets y WML
20001215   Programación de Servlets y WML20001215   Programación de Servlets y WML
20001215 Programación de Servlets y WML
 
Introducción a Java EE
Introducción a Java EEIntroducción a Java EE
Introducción a Java EE
 
Mi primer programa en Symfony2
Mi primer programa en Symfony2Mi primer programa en Symfony2
Mi primer programa en Symfony2
 

Similar a Introducción al framework Spring

Similar a Introducción al framework Spring (20)

spring framework
spring frameworkspring framework
spring framework
 
Greach 2011 : Creando Plugins Con Griffon
Greach 2011 : Creando Plugins Con GriffonGreach 2011 : Creando Plugins Con Griffon
Greach 2011 : Creando Plugins Con Griffon
 
Manual Basico De Struts
Manual Basico De StrutsManual Basico De Struts
Manual Basico De Struts
 
Curso de Desarrollo Web 2
Curso de Desarrollo Web 2Curso de Desarrollo Web 2
Curso de Desarrollo Web 2
 
TEMA Nº 3: ELEMENTOS DE JSP
TEMA Nº 3: ELEMENTOS DE JSPTEMA Nº 3: ELEMENTOS DE JSP
TEMA Nº 3: ELEMENTOS DE JSP
 
La Arquitectura De Netbeans V2
La Arquitectura De Netbeans V2La Arquitectura De Netbeans V2
La Arquitectura De Netbeans V2
 
Fondo1 (2)
Fondo1 (2)Fondo1 (2)
Fondo1 (2)
 
Workshop iOS 3: Testing, protocolos y extensiones
Workshop iOS 3: Testing, protocolos y extensionesWorkshop iOS 3: Testing, protocolos y extensiones
Workshop iOS 3: Testing, protocolos y extensiones
 
Manual Swing-Java-PostgreSQL
Manual Swing-Java-PostgreSQLManual Swing-Java-PostgreSQL
Manual Swing-Java-PostgreSQL
 
Tutorial java fx_8_espanol
Tutorial java fx_8_espanolTutorial java fx_8_espanol
Tutorial java fx_8_espanol
 
Java desde cero
Java desde ceroJava desde cero
Java desde cero
 
MANUAL JAVA
MANUAL JAVA MANUAL JAVA
MANUAL JAVA
 
JAVA
JAVA JAVA
JAVA
 
JAVA 2
JAVA 2JAVA 2
JAVA 2
 
MANUAL DE JAVA
MANUAL DE JAVAMANUAL DE JAVA
MANUAL DE JAVA
 
OSGi
OSGiOSGi
OSGi
 
Introduccion actionscript
Introduccion actionscriptIntroduccion actionscript
Introduccion actionscript
 
Depurando Java Script - Programador PHP
Depurando Java Script - Programador PHPDepurando Java Script - Programador PHP
Depurando Java Script - Programador PHP
 
Hands-on Spring 3: The next generation
Hands-on Spring 3: The next generationHands-on Spring 3: The next generation
Hands-on Spring 3: The next generation
 
investigacion unidad tres componentes y librerias
investigacion unidad tres componentes y libreriasinvestigacion unidad tres componentes y librerias
investigacion unidad tres componentes y librerias
 

Último

5° SEM29 CRONOGRAMA PLANEACIÓN DOCENTE DARUKEL 23-24.pdf
5° SEM29 CRONOGRAMA PLANEACIÓN DOCENTE DARUKEL 23-24.pdf5° SEM29 CRONOGRAMA PLANEACIÓN DOCENTE DARUKEL 23-24.pdf
5° SEM29 CRONOGRAMA PLANEACIÓN DOCENTE DARUKEL 23-24.pdfOswaldoGonzalezCruz
 
periodico mural y sus partes y caracteristicas
periodico mural y sus partes y caracteristicasperiodico mural y sus partes y caracteristicas
periodico mural y sus partes y caracteristicas123yudy
 
el CTE 6 DOCENTES 2 2023-2024abcdefghijoklmnñopqrstuvwxyz
el CTE 6 DOCENTES 2 2023-2024abcdefghijoklmnñopqrstuvwxyzel CTE 6 DOCENTES 2 2023-2024abcdefghijoklmnñopqrstuvwxyz
el CTE 6 DOCENTES 2 2023-2024abcdefghijoklmnñopqrstuvwxyzprofefilete
 
Plan Año Escolar Año Escolar 2023-2024. MPPE
Plan Año Escolar Año Escolar 2023-2024. MPPEPlan Año Escolar Año Escolar 2023-2024. MPPE
Plan Año Escolar Año Escolar 2023-2024. MPPELaura Chacón
 
Mapa Mental de estrategias de articulación de las areas curriculares.pdf
Mapa Mental de estrategias de articulación de las areas curriculares.pdfMapa Mental de estrategias de articulación de las areas curriculares.pdf
Mapa Mental de estrategias de articulación de las areas curriculares.pdfvictorbeltuce
 
c3.hu3.p1.p2.El ser humano y el sentido de su existencia.pptx
c3.hu3.p1.p2.El ser humano y el sentido de su existencia.pptxc3.hu3.p1.p2.El ser humano y el sentido de su existencia.pptx
c3.hu3.p1.p2.El ser humano y el sentido de su existencia.pptxMartín Ramírez
 
BIOLOGIA_banco de preguntas_editorial icfes examen de estado .pdf
BIOLOGIA_banco de preguntas_editorial icfes examen de estado .pdfBIOLOGIA_banco de preguntas_editorial icfes examen de estado .pdf
BIOLOGIA_banco de preguntas_editorial icfes examen de estado .pdfCESARMALAGA4
 
Presentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptx
Presentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptxPresentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptx
Presentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptxYeseniaRivera50
 
programa dia de las madres 10 de mayo para evento
programa dia de las madres 10 de mayo  para eventoprograma dia de las madres 10 de mayo  para evento
programa dia de las madres 10 de mayo para eventoDiegoMtsS
 
PPT GESTIÓN ESCOLAR 2024 Comités y Compromisos.pptx
PPT GESTIÓN ESCOLAR 2024 Comités y Compromisos.pptxPPT GESTIÓN ESCOLAR 2024 Comités y Compromisos.pptx
PPT GESTIÓN ESCOLAR 2024 Comités y Compromisos.pptxOscarEduardoSanchezC
 
TEST DE RAVEN es un test conocido para la personalidad.pdf
TEST DE RAVEN es un test conocido para la personalidad.pdfTEST DE RAVEN es un test conocido para la personalidad.pdf
TEST DE RAVEN es un test conocido para la personalidad.pdfDannyTola1
 
Estrategia de Enseñanza y Aprendizaje.pdf
Estrategia de Enseñanza y Aprendizaje.pdfEstrategia de Enseñanza y Aprendizaje.pdf
Estrategia de Enseñanza y Aprendizaje.pdfromanmillans
 
Estrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdf
Estrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdfEstrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdf
Estrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdfAlfredoRamirez953210
 
Clasificaciones, modalidades y tendencias de investigación educativa.
Clasificaciones, modalidades y tendencias de investigación educativa.Clasificaciones, modalidades y tendencias de investigación educativa.
Clasificaciones, modalidades y tendencias de investigación educativa.José Luis Palma
 
Procesos Didácticos en Educación Inicial .pptx
Procesos Didácticos en Educación Inicial .pptxProcesos Didácticos en Educación Inicial .pptx
Procesos Didácticos en Educación Inicial .pptxMapyMerma1
 
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptx
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptxOLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptx
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptxjosetrinidadchavez
 
CIENCIAS NATURALES 4 TO ambientes .docx
CIENCIAS NATURALES 4 TO  ambientes .docxCIENCIAS NATURALES 4 TO  ambientes .docx
CIENCIAS NATURALES 4 TO ambientes .docxAgustinaNuez21
 

Último (20)

5° SEM29 CRONOGRAMA PLANEACIÓN DOCENTE DARUKEL 23-24.pdf
5° SEM29 CRONOGRAMA PLANEACIÓN DOCENTE DARUKEL 23-24.pdf5° SEM29 CRONOGRAMA PLANEACIÓN DOCENTE DARUKEL 23-24.pdf
5° SEM29 CRONOGRAMA PLANEACIÓN DOCENTE DARUKEL 23-24.pdf
 
periodico mural y sus partes y caracteristicas
periodico mural y sus partes y caracteristicasperiodico mural y sus partes y caracteristicas
periodico mural y sus partes y caracteristicas
 
el CTE 6 DOCENTES 2 2023-2024abcdefghijoklmnñopqrstuvwxyz
el CTE 6 DOCENTES 2 2023-2024abcdefghijoklmnñopqrstuvwxyzel CTE 6 DOCENTES 2 2023-2024abcdefghijoklmnñopqrstuvwxyz
el CTE 6 DOCENTES 2 2023-2024abcdefghijoklmnñopqrstuvwxyz
 
Plan Año Escolar Año Escolar 2023-2024. MPPE
Plan Año Escolar Año Escolar 2023-2024. MPPEPlan Año Escolar Año Escolar 2023-2024. MPPE
Plan Año Escolar Año Escolar 2023-2024. MPPE
 
Sesión de clase: Defendamos la verdad.pdf
Sesión de clase: Defendamos la verdad.pdfSesión de clase: Defendamos la verdad.pdf
Sesión de clase: Defendamos la verdad.pdf
 
Mapa Mental de estrategias de articulación de las areas curriculares.pdf
Mapa Mental de estrategias de articulación de las areas curriculares.pdfMapa Mental de estrategias de articulación de las areas curriculares.pdf
Mapa Mental de estrategias de articulación de las areas curriculares.pdf
 
c3.hu3.p1.p2.El ser humano y el sentido de su existencia.pptx
c3.hu3.p1.p2.El ser humano y el sentido de su existencia.pptxc3.hu3.p1.p2.El ser humano y el sentido de su existencia.pptx
c3.hu3.p1.p2.El ser humano y el sentido de su existencia.pptx
 
BIOLOGIA_banco de preguntas_editorial icfes examen de estado .pdf
BIOLOGIA_banco de preguntas_editorial icfes examen de estado .pdfBIOLOGIA_banco de preguntas_editorial icfes examen de estado .pdf
BIOLOGIA_banco de preguntas_editorial icfes examen de estado .pdf
 
Presentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptx
Presentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptxPresentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptx
Presentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptx
 
Earth Day Everyday 2024 54th anniversary
Earth Day Everyday 2024 54th anniversaryEarth Day Everyday 2024 54th anniversary
Earth Day Everyday 2024 54th anniversary
 
programa dia de las madres 10 de mayo para evento
programa dia de las madres 10 de mayo  para eventoprograma dia de las madres 10 de mayo  para evento
programa dia de las madres 10 de mayo para evento
 
PPT GESTIÓN ESCOLAR 2024 Comités y Compromisos.pptx
PPT GESTIÓN ESCOLAR 2024 Comités y Compromisos.pptxPPT GESTIÓN ESCOLAR 2024 Comités y Compromisos.pptx
PPT GESTIÓN ESCOLAR 2024 Comités y Compromisos.pptx
 
TEST DE RAVEN es un test conocido para la personalidad.pdf
TEST DE RAVEN es un test conocido para la personalidad.pdfTEST DE RAVEN es un test conocido para la personalidad.pdf
TEST DE RAVEN es un test conocido para la personalidad.pdf
 
Power Point: "Defendamos la verdad".pptx
Power Point: "Defendamos la verdad".pptxPower Point: "Defendamos la verdad".pptx
Power Point: "Defendamos la verdad".pptx
 
Estrategia de Enseñanza y Aprendizaje.pdf
Estrategia de Enseñanza y Aprendizaje.pdfEstrategia de Enseñanza y Aprendizaje.pdf
Estrategia de Enseñanza y Aprendizaje.pdf
 
Estrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdf
Estrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdfEstrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdf
Estrategias de enseñanza - aprendizaje. Seminario de Tecnologia..pptx.pdf
 
Clasificaciones, modalidades y tendencias de investigación educativa.
Clasificaciones, modalidades y tendencias de investigación educativa.Clasificaciones, modalidades y tendencias de investigación educativa.
Clasificaciones, modalidades y tendencias de investigación educativa.
 
Procesos Didácticos en Educación Inicial .pptx
Procesos Didácticos en Educación Inicial .pptxProcesos Didácticos en Educación Inicial .pptx
Procesos Didácticos en Educación Inicial .pptx
 
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptx
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptxOLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptx
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptx
 
CIENCIAS NATURALES 4 TO ambientes .docx
CIENCIAS NATURALES 4 TO  ambientes .docxCIENCIAS NATURALES 4 TO  ambientes .docx
CIENCIAS NATURALES 4 TO ambientes .docx
 

Introducción al framework Spring

  • 2. Spring es un framework ligeropara el desarrollo de aplicaciones. Strtus, WebWork y otros son frameworks para web. Spring, por contra, dasoporte a todaslascapas de unaaplicación. Nosevita “la fontanería” quenormalmente el desarrollador se veobligado a implementara mano. ¿Quées Spring?
  • 3. Publicado en 2002/2003 por Rod Johnson y JuergenHoller Empezósiendo un ejemplo en el libroExpert One-on-One J2EE Design and Development de Rod Johnson. Spring 1.0 se publica en marzo del 2004 A partir de 2004/2005 Spring se popularizacomo framework de desarrolloparaaplicaciones Java/J2EE Historia de Spring…
  • 4. Spring no es un servidor de aplicaciones JEE, sinoque se integra en lasaplicacionesque se despliegansobreellos, y sobreaplicaciones Java en general. Spring sustituye ¿elegantemente? algunosde los serviciosqueaportan los servidores de aplicaciones JEE. ¿Spring & JEE?
  • 5. Spring propone unaestructuraconsistenteparatoda la aplicación Facilita un métodoconsistenteparapegartodos los elementos de la aplicación. Abierto a la integración con múltiplesestándares e implementacionespopularescomo: Hibernate, JDO, TopLink, EJB, RMI, JNDI, JMS, Web Services, Struts, etc. Permiteaumentarnuestraproductividadevitándo al desarrollador la tarea de implementartareasderivadas de la integración de los componentes de la aplicación. ¿Quéaporta Spring?
  • 6. From springframework.org Los creadores de Spring defiendenque: JEE debería ser mássencilla de usar Es preferibleprogramar interfaces a programarclases, peroéstoconllevausualmente un costeadicional de implementación. Spring lo facilitareduciendo la implementacióndesacopladabasándose en interfaces. La especificación de JavaBeans ofrececiertasventajas a la hora de externalizar y modularizar la configuración de lasaplicaciones. El paradigma OO debeimponersesobre la tecnologíasubyacentecomo _JEE Filosofíade Spring
  • 7. Filosofía POJO, menos interfaces y excepcioneschequeadasquefuerzan a complicar el códigocuandointegramoselementosdiferentes. La prueba del software son esenciales. Spring nosayuda a implementarcódigochequeablemediantepruebasunitarias. La aplicación de Spring debe ser placentera. El código de la aplicación no debedepender de las APIs de Spring. Spring no debecompetir con solucionesqueyafuncionan, sinopermitirsufácilintegración en la aplicación (Ej, Hibernate, JDO, etc.) Filosofíade Spring
  • 9. ¿Quéimplicaesto? No fuerza a importar o extender ninguna API de Spring. Unatecnologíainvasivacomprometenuestrocódigo con susimplementaciones- Anti-patrones: EJB nosfuerza a usar JNDI Struts 1.x fuerza a extender la claseAction Los Frameworks invasivos son por lo general difíciles de testear. Tecnología no invasiva
  • 10. Fundamentalmente, Spring se compone de: Contenedor de inversión de control (IoC) Aplicación de la técnica de inyección de dependencias (Fowler) Un framework AOP. Spring facilita un framework AOP basado en proxy. Integrable con AspectJ o AspectWerkz Unacapa de abstracción de servicios Integraciónconsistente con variosestándares y APIs populares. Todoelloestábasado en la implementación de aplicacionesusando POJOs. Estructura de Spring
  • 12. Gestiona objetos como componentes, permitiendo: Crearlos Configurarlos “Cablearlos” (Wiring) – Enlazado entre objetos. Controlar todo si ciclo de vida Controlar su destrucción Ofrece varios tipos de contenedor diferentes, clasificables en dos tipos: BeanFactory ApplicationContext (más completo) ¿Para qué vale?
  • 13. Descarguemos el piloto 1.0 y analicemos su código. ¿Funciona? ¿Cómo están las clases? ¿Con cuantos tipos de actores puede funcionar el espectáculo que estamos modelando? ¿Qué tengo que hacer para variar el tipo de actor? Aplicaciones fuertemente acopladas
  • 14.
  • 16. tenga un método ObjectgetService(String) que cuando reciba “Malabarista” devuelva una instancia de la clase Malabarista.(Resuelto en piloto 3.0) Refactorizando…
  • 17. El BeanFactoryesunaimplementación del patrónfactoríaquepermitecrear beans declarándolos en un ficheros XML cuyaraizes la etiqueta <beans> El XML contieneuno o máselementos de tipo <bean> Atributoid (o nombre) paraidentificar el bean Atributoclass queespecifica el nombrecualificadocompleto de la clasequeimplementará el bean bautizado con id El contenedorBeanFactory
  • 18. Pordefecto, los beans son tratadoscomosingletons (Dessign patterns, GoF’94),aunqueexistenotrosposiblespatrones de comportamiento. Ejemplo: El contenedorBeanFactory The bean’s fully- qualified classname The bean’s ID <beans> <bean id=“widgetService” class=“com.zabada.base.WidgetService”> </bean> </beans>
  • 19. Para utilizarlo: BeanFactoryfactory = new XmlBeanFactory(<documento xml>); Factory.getBean(<identificador del bean>); El documento XML debe ser encapsuladoporalguna de lassiguientesclases wrapper. El contenedor BeanFactory
  • 20. El documento XML declara los beans, asociándoles el identificador por el cual van a ser referenciados. <?xmlversion="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="actor" class="es.uniovi.si.Malabarista"/> </beans> El contenedor BeanFactory
  • 21. Descargar piloto 4.0 y examinar el código fuente. Extender ésta versión del piloto para que la clase Show: Implemente un interfaz evento que contenga su método de comienzo. Sea también creada por medio de la factoría BeanFactory, bajo el id de evento. (Resuelto en piloto 5.0) Taller práctico
  • 22. El ciclo de vida con BeanFactory
  • 23. El ciclo de vida con BeanFactory
  • 24. A partir del piloto 5.0, Definir un constructor público en la clase Malabarista que inicialice el número de objetos con los que hace los malabarismos. Modificar el bean.xml para que reciba 15 como parámetro de constructor al crear el bean. Probarlo Una vez comprobado, sobrecargamos el constructor con otro que reciba una cadena de texto y la muestre por pantalla. ¿Qué sucede? Añadir la etiqueta type para forzar a que se dispare el constructor que nos interesa. (resuelto en piloto 6.0) Taller práctico
  • 25. Es el segundo tipo de inyección de dependencias posible. En lugar de pasarle la información por medio del método constructor, le decimos a Spring que le haga llegar la propiedad en el bean.xml Para ello debemos: Tener un método set para la propiedad Añadir una etiqueta property anidada a la definición del bean en el bean.xml <property name ="numeroObjetos" value="15"/> Inyección de parámetros por métodos setter
  • 26. Además de valores sencillos, es posible inyectar una referencia a otro bean dado de alta en el contenedor. Ejemplo: <bean name=“widgetService” class=“com.zabada.base. WidgetServiceImpl”> <property name=“widgetDAO”> <ref bean=“myWidgetDAO”/> </property> </bean> Esto implica que la clase WidgetServiceImpldeberátener un métodosetWidgetDAO(WidgetServiceImpl ref) Inyección de referencias de objetos
  • 27. Modificar el piloto para que la clase Show reciba como dependencia la instancia de la clases Malabarista en su propiedad actor. (Resuelto en piloto 7.0) Taller práctico
  • 28. Es una extensión del BeanFactory (hereda de él) Permite más opciones: Incorpora mecanismos para la externalización de cadenas de texto e internacionalización (i18n) Unifica la carga de recursos, como las imágenes. Permite implementar un modelo de paso de mensajes mediante eventos a los beans, declarándolos como listeners del evento. Por lo general, se usa éste en lugar del BeanFactory, a no ser que estemos en entornos de recursos restringidos (dispositivos móviles o similares). El Contenedor ApplicationContext
  • 29. Hay tres implementaciones del contenedor: Ejemplo: ApplicationContextcontext = new FileSystemXmlApplicationContext("c:/foo.xml"); El Contenedor ApplicationContext
  • 30. El ciclo de vida con ApplicationContext
  • 31. Descargar la versión 8.0 del piloto y examinar el código fuente. Ejecutarlo para comprobar que funciona correctamente. Taller práctico
  • 32. Vamos a extender el piloto 8.0 de forma que: Aparezca una interfaz Instrumento con el método toca() que devuelve un String. Aparezca una clase Saxofon que implemente la interfaz Instrumento y suene “tuuuuttuuuuututuuuuutuuuu” Aparezca un nuevo actor de tipo Instrumentista tal que: Reciba por setter: Nombre El instrumento que toca Al actuar, muestre un mensaje diciendo que “fulanito hace …” con el sonido que haga el instrumento que esté tocando Damos de alta un nuevo beankenny, que se llame Kenny G , que toque el saxofón y hacemos que sea él el que actúe en el Show. Resuelto en piloto 9.0 Taller práctico – Juntándolo todo
  • 33. Supuesto: Contratamos a otro saxofonista para el Show: <bean id="kenny" class="com.springinaction.springidol.Instrumentalist"> <propertyname=“nombre“ value=“juan”/> <propertyname="instrument"> <refbean="saxofon"/> </property> </bean> Pero…: A Kenny G (que “ye” muy fino) no le gusta compartir el saxofón ¿Cuántas instancias se crean del instrumento? Problema
  • 34. Inspirados en las innerclassesde Java (Clases que de definen dentro de otras clases) Los innerbeans son beans que se definen dentro de otros beans, y cuyo ámbito se reduce al bean contenedor. El bean contenido sólo será accesible por el que lo contiene: <propertyname="instrument"> <beanclass="org.springinaction.springidol.Saxophone" /> </property> (Ver ejemplo en piloto 10.0) InnerBeans
  • 35. Hasta ahora hemos visto como utilizar Spring para configurar propiedades simples, de un solo valor o referencia. Pero… ¿Cómo hacerlo cuando tratamos con colecciones? Spring permite trabajar con cuatro tipos de colecciones. Cableado de colecciones
  • 36. Si quisiéramos que en Show participasen kennyy el beanactor. Modificaremos la clase Show para que: En lugar de tener un atributo de tipo actor, lo tenga de tipo Collection<Actor>, con su correspondiente método setActores(…) Al comenzar el show, haga actuar a todos los actores del espectáculo que encuentre en la colección. for ( Actor actor:actores ){ actor.actua(); } Extendemos el beans.xml para anidar a los dos actores <propertyname="actores"> <list> <refbean…/> … </list> Resuelto en piloto 11.0 Cableado de colecciones
  • 37. A partir del piloto 10, completarlo para que entre el malabarista y el saxofonista, actúe un hombre orquesta que toque el saxofón, la armónica y la guitarra. La armónica es suya y no la comparte, pero la guitarra es de la organización del show. Usaremos por convenio los nombres: Clase Guitarra. Clase Armonica Clase HombreOrquesta Clase Hombre orquesta: Benja (Resuelto en piloto 11.0) Taller práctico: Repasando
  • 38. Para “cablear” un Map, El objeto se tiene que esperar que le pasen como parámetro una instancia de la clase Map. PublicvoidsetInstrumentos(Map <String,Instrumento>)… El beans.xml debe enlazar el mapa con el parámetro instrumentos. <map> <entrykey="la guitarra" value-ref="fender" /> … Cableado de Mapas
  • 39. Extender piloto 11.0 para que en lugar de pasar directamente las referencias a los beans que toca el Hombre Orquesta, le pasemos un mapa con el nombre que le queramos dar al instrumento, de forma que el mensaje al tocarlo sea… “El hombre orquesta toca la guitarra: rrriaaannnriiiaaaannnriiiiaaaannnnnnnn” Resuelto en piloto 12 Taller práctico
  • 40. Modificar el piloto 12 para que: A cada actor pueda asignársele un nombre artístico cada vez que se enlace al show La salida una vez resuelto, será algo como: Presentamos a Tony Malabares Haciendo malabarismos con 15 objetos Presentamos a El Increible hombre orquesta El hombre orquesta toca la guitarra:rrriaaannnriiiaaaannnriiiiaaaannnnnnnn El hombre orquesta toca la armónica:tui tui tuiiiiiituiiiiiii Presentamos a Kenny G! Kenny G hace ttuuuuuutuuuutuuuuututuuuuuuuu Resuelto en piloto 13 Taller práctico
  • 41. Hemos visto como “cablear” beans Con el elemento <constructor-arg> Con el elemento <property> Problema: En una aplicación complicada, esta práctica puede degenerar en un XML desmesurado e inmanejable. Alternativa: En lugar de definir explícitamente las relaciones entre beans, podemos dejar que Spring decida como debe cablearlos, mediante la propiedad autowire del elemento <bean> Auto-Cableado en Spring(Autowire)
  • 42. Tipos de autocableado: Auto-Cableado en Spring(Autowire)
  • 43. Todo en Spring tiene un nombre. <bean id="kenny" class="es.uniovi.si.Instrumentista"> <property name="nombre" value="Kenny G"/> <propertyname="instrumento"> <beanclass="es.uniovi.si.Saxofon"/> </property> </bean> Si queremos simplificar el XML: <bean id=“instrumento” class="es.uniovi.si.Saxofon"/> … <bean id="kenny" class="es.uniovi.si.Instrumentista“ autowire=“byName”> <property name="nombre" value="Kenny G"/> </bean> Lo cambiamos y lo probamos. ¿Funciona? (Resuelto en piloto 14.0) AutowirebyName
  • 44. Similar a byName, salvo que la búsqueda la realiza por tipo, y no por nombre Por cada beanautocableado por tipo, Introspecciona las propiedades del bean Por cada setXXX no cableado explícitamente en el beans.xml, busca un bean declarado que coincida en tipo con la propiedad, y si lo encuentra, lo cablea. Probamos: Partiendo del piloto 14.0, cambiar el autowire a byType. ¿Funciona? ¿Qué podemos hacer para arreglarlo? (Resuelto en piloto 15.0) AutowirebyType
  • 45. Útil cuando utilizamos inyección de dependencias en el constructor. Si declaramos un beanautocableable por constructor: Spring busca por instrospección los constructores del bean Por cada uno, trata de buscar candidatos para satisfacer los tipos de sus parámetros entre los beans declarados en el beans.xml Si los encuentra, invoca el constructor. En caso de ambigüedad, dispara una excepción igual que cuando usamos byType Autowire por constructor
  • 46. Nos permite delegar en el contenedor la decisión de qué bean debe ser cableado con otro, y de qué forma. <bean id="duke" class="com.springinaction.springidol.PoeticJuggler" autowire="autodetect" /> Para este ejemplo, Spring tratará de autocablear el bean por constructor, y en caso de no tener éxito, lo intentará por tipo. Autodetección de autowire
  • 47. Si vamos a adoptar una política común de autocableado para todos los beans, podemos declararla a nivel de contenedor: <beansdefault-autowire="byName"> … </beans> Esta propiedad se puede sobrescribir a nivel de bean individual. Autocableado por defecto
  • 48. Hasta ahora hemos usado la creación básica de beans, asumiendo que Spring crea una única instancia de cada uno. Existen más opciones para gestionar la instanciación de beans: Control del número de instancias creadas Singleton Una por request Una por petición Creación mediante factoría Incialización y destrucción controlada del bean Control del ciclo de vida del Bean
  • 49. Por defecto, todos son singleton Problema: en determinados contextos, no podemos/queremos usar singletons. Utilizando el atributo scope del elemento bean determinamos su ciclo de vida: Control del ciclo de vida del BeanControl del ámbito (scope) del bean
  • 50. Si queremos definir un bean como prototype: <bean id=<identificador> class=<nombre de la clase> scope={prototype |singleton |request |session |global-session/> Uso del atributo scope
  • 51. Modificar la versión 15 del piloto para que: El bean instrumento se instancie una vez por cada bean que lo utilice El Hombre Orquesta lo añada a su colección de instrumentos Junto con el “sonido” del saxofón, se muestre el valor de la referencia del objeto que lo identifica unívocamente en la JVM. Si ahora quitamos el scope… ¿Hay diferencia? (Resuelto en piloto 16.0) Taller práctico
  • 52. Normalmente creamos las clases con su constructor público, pero por distintos motivos (código heredad, librerías de terceras partes, etc.), es posible que el bean que queremos “cablear” deba ser creado a partir de un factorymethod Ejemplo: Queremos incorporar a modelo del Show un escenario que tenemos ya implementado de otra parte del sistema. Como es único, viene implementado como singlenton. Creación de beans desde factorías
  • 53. Para la instanciación de este tipo de objetos, el elemento bean permite especificar el factory-method que debe invocar el contenedor para obtener una instancia del bean. <bean id=“<identificador>" class=“<nombre de la clase>" factory-method=“<método que retorna la instancia>" /> Creación de beans desde factorías
  • 54. A partir del piloto 16.0: Crear una clase Escenario que implemente el patrón singleton, y llamamos al método de creación de instancia getInstancia(). Sobrescribir su método toString para que retorne “Escenario Central”. Modificar la aplicación para que el Show, antes de comenzar la actuación, obtenga una referencia al escenario y muestre por pantalla: Bienvenidos al Escenario Central (Resuelto en trabajo 17.0) Taller práctico
  • 55. Es posible que un determinado bean requiera hacer operaciones de inicialización antes de poder realizar su tarea, o bien liberar recursos –conexiones a bbdd, cierre ficheros, etc- antes de su destrucción. Los atributos: init-method destroy-method nos permiten decirle al contenedor qué dos métodos queremos que realicen estas tareas de inicialización y destrucción. Al igual que con autowire, se pueden especificar los nombres de los métodos constructor y destructor a nivel de contenedor con default-init-methody default-destroy-method. Inicialización y destrucción de beans
  • 56. A partir de trabajo 17.0: Implementar en el saxofón y en la armónica un método afinar y otro limpiar que publiquen sendos mensajes por la consola. Hacer que ambos se disparen como método de inicialización y método de destrucción. Probarlo. ¿Funciona? ¿Y si ahora lo pongo por defecto para todos los beans? <beans default-init-method="afinar" default-destroy-method="limpiar"> Taller práctico
  • 57. Modificar y extender la clase Escenario para que tenga los métidos abrirTelon cerrarTelon Que impriman sendos mensajes y que sea invocado al inicializar y al destruir la clase. Taller práctico
  • 58. A partir del ejemplo anterior una vez terminado, probar a forzar a que la clase Instrumentista implemente las interfaces InitializingBean DisposableBean ¿Qué ocurre? Hacer lo necesario para que sea compilable y ejecutarlo. Resuelto en piloto 18.0 Inicialización por I.D. por interfaces
  • 59. Modificar la clase Escenario de nuevo para que la inicialización y destrucción se realicen ahora por usando los dos interfaces: InitializingBean DisposableBean Taller práctico
  • 61. Hasta ahora hemos declarado los beans de forma individual, estableciendo las propiedades de cada uno una a una de forma específica. Problema: Puede degenerar en ficheros de configuración muy extensos y poco tratables. Ejemplo: Tenemos muchos beans de un determinado tipo que comparten características ->Tenemos que definir la misma característica en todos ellos. En una orquesta, todos los instrumentistas tocan la misma canción Herencia
  • 62. Al igual que en la POO, es posible definir relaciones padre-hijo entre los beans declarados en un contenedor. Un bean que extiende la declaración de otro bean se define como sub-bean del segundo. Dos atributos específicos para esto: Parent: Declara de qué bean hereda el que estamos declarando Abstract: Declara el bean como abstracto, y por lo tanto, no instanciable. Herencia
  • 63. <bean id=“<nombre padre>" class=“<clase del padre>" abstract="true"> <propertyname=“<propiedad común>" ref=“<refbean a heredar>"/> </bean> <bean id=”<hombre hijo 1>" parent=”<nombre padre>"> <property name=“<otrapropiedad>" value=“<valor 1>"/> </bean> <bean id=”<hombre hijo 2>" parent=”<nombre padre>"> <property name=“<otrapropiedad>" value=“<valor 2>"/> </bean> Ejemplo
  • 64. Modificar el piloto a partir de su versión 18 para que: Aparezca un bean Saxofonista que: Sea abstracto Esté ligado al Saxofón En el show participe un nuevo saxofonista con id=“bill” y nombre=“Bill Clinton”. Será presentado como “El presidente Clinton!”. Resuelto en trabajo 19.0 Taller práctico
  • 65. Extender ahora el piloto 19.0 para que: Tanto los instrumentistas como los hombres orquesta tengan un atributo de tipo String que se llame tema. Poner a todos los implicados de acuerdo para que toquen “Paquito el Chocolatero” ... ¿Se repite configuración? ¿Debemos ligar el atributo tema a la clase Actor? ¿Y el malabarista? ¿Creamos una nueva clase intermedia? Taller práctico - repaso
  • 66. En determinados contextos, puede que necesitemos compartir valores de propiedades entre beans de diferentes clases. Spring permite hacer esto declarando un bean abstracto sin especificar su clase, y forzando a los hijos a que lo extiendan. <bean id=“<bean base>" abstract="true"> <property name=“<nombrepropiedadcompartida>" value=“<valor de la propriedad>" /> </bean> Abstracción de propiedades comunes
  • 67. Definir un bean abstracto Interprete que defina el valor de la propierdad tema para que toque “Paquito el chocolatero” y configurar los bean “Hombre Orquesta” y “Saxofonista” para que hereden dicha propiedad del intérprete. (Resuelto en piloto 20.0) Taller práctico
  • 68. Habitual el lenguajes dinámicos como Ruby. Consiste en añadir nuevos métodos a una clase ya compilada, o modificar la definición de alguno ya existente. En Java y otros LOO “clásicos” no se puede hacer esto, son “poco flexibles” Spring permite “simular” la inyección de métodos en los beans que tenga declarados en el contenedor. Dos tipos: Remplazo de métodos Inyección de Getter Inyección de métodos
  • 69. Spring interceptará las invocaciones que se realicen al método sustituido para inyectar en medio la nueva implementación del mismo Es necesario implementar un objeto que cumpla la interfaz MethodReplacer public class <NombreClase> implements MethodReplacer { public Object reimplement(Object target, Method method, Object[] args) throwsThrowable{ ... } Remplazo básico de método
  • 70. Una vez dado de alta, sustituimos el método en el beans.xml <bean id="<bean sustituto>" class=“<clase methodreplacer>"/> <bean ...> ... <replaced-methodname=“<método a sustituir>” replacer=“<bean sustituto>"/> </bean> Remplazo básico de método
  • 71. Descargar piloto 20.0 (importante partir de éste, incluye nuevas referencias a jars) y extenderlo para sustituir el sonido del saxofón. Para ello: Implementar una clase Sintentizador que modifique el sonido del saxofón, retornando una nueva cadena de sonido. Darlo de alta en el beans.xml como sintentizador y utilizar el elemento replaced-method en el beansinstrumento para sobrescribir el método toca. ¿Funciona? ¿Qué clase está realmente ejecutándose? Añadir a la nueva cadena de sonido la referencia al objeto que se ejectura (Wrapper). Resuelto en Versión 21.0 (Ojo!!! Sólo funciona si obtenemos el objeto a través de Spring! Taller práctico
  • 72. Si el método que queremos inyectar es un método getter para que retorne un bean contenido en el contenedor, podemos directamente obviar su implementación y decirle a Spring que intercepte la petición. <bean id=“<nombre bean>” class=“<clase del bean>”> … <lookup-methodname=“<nombre getter>" bean=“<bean a retornar>"/> </bean> Inyección de Getter
  • 73. Vamos a darle “el cambiazo” a kenny, sustituyéndole el saxofón por la guitarra fender. Para ello, Modificamos el método actua de la clase Instrumentista para que cuando acceda al instrumento lo haga a través de su método getter. Transformamos el innerbeanfenderen uno normal para que pueda ser accedido desde otros beans. Sobrescribimos el getter de kenny para que getInstrumento retorne el beanfender. (Resuelto en piloto 21.0) ¿Qué clase está realmente implementando el método actúa? Taller práctico
  • 74. Las propiedades vistas hasta ahora son simples, pero normalmente nos enfrentamos a estructuras más complejas Ej: Reconocer y procesar una URL: http://www.xmethods.net/sd/BabelFishService.wsdl Spring, puede convertir automáticamente el texto anterior en un objeto de tipo URL. ¿Cómo lo hace? Mediante un property editor basado en la especificación de Java Beans. Registrando editores de propiedades personalizados
  • 75. Interfaz java.beans.PropertyEditor Permite especificar como se deben mapear datos de tipo String en tipos no String. Fuerza a tener dos métodos: getAsText()- Devuelve la representación en forma de String del valor setAsText(String) – Transforma el String que recibe en el formato correspondiente. Si se trata de dar un valor de tipo String a una propiedad que no lo es, se disparará el método setAsText() para realizar la conversión. getAsText() se usará para representar el valor. El interfaz PropertyEditor
  • 76. Spring incorpora varios editores de propiedades a medida, basados en la clase PropertyEditorSupport. PropertyEditors de Spring
  • 77. Podemos desarrollar nuestro propio editor de propiedades personalizado para nuestra aplicación. Ejemplo (A partir de piloto 22.00): Vamos a añadir información de contacto a todos los instrumentistas. Creamos una clase Telefono con los atributos codigoPais numero extension Y sus correspondientes getters y constructor parametrizado. Desarrollo de PropertyEditors a medida
  • 78. Añadimos una instancia de la clase Telefono como propiedad de la clase Instrumentista Y ahora configuraremos el contenedor para asignarle un teléfono a Kenny G. <bean id="telefono1" class="es.uniovi.si.Telefono"> <constructor-argvalue="0034"/> <constructor-argvalue="985105094"/> <constructor-argvalue="00"/> </bean> <bean id="kenny" parent="Saxofonista"> <property name="nombre" value="Kenny G"/> <propertyname="telefono" ref="telefono1"/> <lookup-methodname="getInstrumento" bean="fender"/> </bean> ¿Funciona? Sí, pero es tedioso y poco práctico Desarrollo de PropertyEditors a medida
  • 79. Alternativa: Creamos nuestro propio PropertyEditor: public class TelefonoPropertyEditor extends PropertyEditorSupport { publicvoidsetAsText(String texto){ Stringstripped = stripNonNumeric(texto); StringcodigoPais = stripped.substring(0,3); String numero = stripped.substring(3,12); Stringextension = stripped.substring(12); Telefonotelefono = new Telefono(codigoPais, numero, extension); setValue(telefono);} privateStringstripNonNumeric(String original) { StringBufferallNumeric = new StringBuffer(); for(int i=0; i<original.length(); i++) { char c = original.charAt(i); if(Character.isDigit(c)) { allNumeric.append(c); } } returnallNumeric.toString();} } Desarrollo de PropertyEditors a medida
  • 80. Ahora sólo nos falta decirle a Spring cuando y como aplicar el nuevo property editor, por medio delCustomEditorConfigurer CustomEditorConfigurer es un BeanPostProcessor que carga los editores de propiedades en la BeanFactory. Para ello: <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"> <propertyname="customEditors"> <map> <entrykey="es.uniovi.si.Telefono"> <bean id="TelefonoEditor" class="es.uniovi.si.TelefonoPropertyEditor"> </bean> </entry> </map> </property> </bean> Desarrollo de PropertyEditors a medida
  • 81. Ahora ya podemos asignárselo directamente a kenny <bean id="kenny" parent="Saxofonista"> <property name="nombre" value="Kenny G" /> <property name="telefono" value="0034-650423932-00" /> <lookup-methodname="getInstrumento" bean="fender" /> </bean> (Resuelto en piloto 23.0) Desarrollo de PropertyEditors a medida
  • 82. Creamos ahora un propertyEditor para el email: Creamos una clase email con dos propiedades: usuario y servidor. Hacemos sus accessors y su constructor parametrizado Añadimos Email como propiedad de instrumentista Creamos el properyeditor para convertir el email email.setUsuario(texto.substring(0,texto.indexOf('@'))); email.setServidor(texto.substring( texto.indexOf('@')+1,texto.length())); Añadimos el nuevo email property editor al map del CustomEditorConfigurer Le asignamos bill.clinton@whitehouse.org al beanbill. Resuelto en 23.5 Taller práctico
  • 83. La mayoría de los beans que manejará el contenedor son tratados de la misma forma – la vista hasta ahora. Para determinadas tareas, Spring permite especificar que determinados beans sean tratados de manera especial. Para marcar aquellos beans que deben ser tratados como tales, nos serviremos de la inyección de dependencias por interfaces. Los beans “especiales de Spring
  • 84. Mediante estos, podemos: Tomar parte en la creación de los beans y en el ciclo de vida de la factoría mediante posprocesamiento. Cargar ficheros de configuración externos –en ficheros property Cargar mensajes de texto, como base para la internacionalización. Ligar el bean a la recepción de eventos. Los beans “especiales de Spring
  • 85. Permiten programar ciertas tareas que se dispararán antes y después de la inicialización de los beans del contenedor El bean de PostProcesamiento se configura POR CONTENEDOR Para esto, tenemos que: Crear un bean que implemente la interfaz BeanPostProcessor Darlo de alta en el contenedor. Beans de posprocesamiento
  • 86. El bean debe implementar la interfaz BeanPostProcessor: public interface BeanPostProcessor { ObjectpostProcessBeforeInitialization( Object bean, String name) throws BeansException; ObjectpostProcessAfterInitialization( Object bean, String name) throws BeansException; } Creación del BeanPostProcessor
  • 87. Tenemos dos alternativas: Si trabajamos con BeanFactory: BeanPostProcessorfuddifier = new Fuddifier(); factory.addBeanPostProcessor(fuddifier); Si trabajamos con ApplicationContext: <beanclass=“<nombre de la clase postprocesadora>"/> En el segundo caso, basta con esto. El propio contenedor se dará cuenta de que el bean instanciado implementa la interfaz BeanPostProcessor y lo incluirá como tal en el ciclo de vida de los beans corrientes. Configurar el postprocesador
  • 88. Queremos desarrollar un postprocesador que “se chive” de quienes están actuando en el Show, de forma que para todo aquel bean que tenga nombre (y por lo tanto, método getNombre()), se genere un mensaje por pantalla notificando que “fulanito” ha actuado. Para ello, habrá que desarrollar el postprocesador darlo de alta en el contenedor Ejemplo: Con hacienda hemos topado
  • 89. publicclassHaciendaPostProcessorimplementsBeanPostProcessor { @Override publicObjectpostProcessAfterInitialization(Objectbean, String arg1) throwsBeansException { try { Methodmethod= bean.getClass().getMethod("getNombre"); if ( method!=null ){ String nombre = (String) method.invoke(bean, null); System.out.println("REGISTRADA ACTUACIÓN DE "+nombre); } } catch (NoSuchMethodException e) { //No hacemos nada. } catch (Exceptionee) { ee.printStackTrace(); } returnbean; } @Override publicObjectpostProcessBeforeInitialization(Objectbean, String arg1) throwsBeansException { returnbean; } } HaciendaPostProcessor
  • 90. Y lo damos de alta en el contenedor <beanclass="es.uniovi.si.HaciendaPostProcessor"/> Resuelto en Piloto 24.0 Taller práctico Descargar el piloto 24.0 Importarlo en Eclipse Examinar el código fuente HaciendaPostProcessor
  • 91. Ahora llega la SGAE! Extender el piloto par añadir un nuevo beanpostprocesadorSGAEPostProcessor que saque por pantalla todos aquellos temas que se toquen en el Show, intentando acceder al método getTema de cada bean declarado en el mismo. (Será necesario añadir el método getTema() a los que ya cuentan con setTema()) (Resuelto en piloto 25.0). Taller práctico: De mal en peor…
  • 92. Similar al BeanPostProcessor, el BeanFactoryPostProcessor permite realizar tareas de postprocesamiento sobre todo el contenedor de Spring. public interface BeanFactoryPostProcessor { voidpostProcessBeanFactory( ConfigurableListableBeanFactorybeanFactory) throwsBeansException; } El método postProcessBeanFactoryes invocado por Spring una vez las definiciones hayan sido cargadas, pero antes de que los beans sean instanciados. Postprocesamiento de la factoría
  • 93. Ejemplo: Para saber cuantos beans han sido declarados en el beans.xml public class BeanCounter implements BeanFactoryPostProcessor { privateLoggerLOGGER = Logger.getLogger(BeanCounter.class); publicvoidpostProcessBeanFactory( ConfigurableListableBeanFactoryfactory) throwsBeansException { LOGGER.debug("BEAN COUNT: " + factory.getBeanDefinitionCount()); } } Para darlo de alta en el contenedor. <bean id="beanCounter”class="com.spring.BeanCounter"/> Postprocesamiento de la factoría
  • 94. Es posible configurar los beans mediante el beans.xml y el elemento <property>. Sin embargo, no conviene mezclar el cableado de beans con la configuración específica de nuestra aplicación. Spring proporciona el objeto PropertyPlaceholderConfigurer si trabajamos con el ApplicationContext para esto. <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value=“<fichero.properties>" /> </bean> Externalizando la configuración de los beans
  • 95. Puede que necesitemos modular la configuración en diferentes ficheros de propiedades: <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <propertyname="locations"> <list> <value>jdbc.properties</value> <value>security.properties</value> <value>application.properties</value> </list> </bean> Externalizando la configuración de los beans
  • 96. Ahora podemos recuperar los valores de configuración referenciándolos por medio de variables en lugar de tenerlos “hardcodeados” en el beans.xml <bean id="dataSource” class= "org.springframework.jdbc.datasource.DriverManagerDataSource"> <propertyname="url” value="${database.url}" /> <propertyname="driverClassName” value="${database.driver}" /> <propertyname="username” value="${database.user}" /> <propertyname="password” value="${database.password}" /> </bean> Externalizando la configuración de los beans
  • 98. Extender el piloto 25.0 para que tome los siguientes datos del fichero Configuracion.properties: numero.malabares=25 tema=19 días y 500 noches (Resuelto en piloto 26.0) Taller práctico
  • 99. En determinados casos, los beans necesitarán tener acceso a objetos de Spring, como el ApplicationContext. Esto se resuelve mediante inyección de dependencias por interfaz. Hay tres posibles interfaces que dan acceso a sendos objetos: BeanNameAware BeanFactoryAware ApplicationContextAware Beansatentos (Aware)
  • 100. Implementando la interfaz BeanNameAware le estoy diciendo al contenedor que queremos que nos inyecte el identificador con el que el bean ha sido declarado en el beans.xml public interface BeanNameAware { voidsetBeanName(Stringname); } Cuando cada bean sea cagado, el contenedor comprobará por introspección si implementa esta interfaz ( isInstanceOf(…)). En tal caso, invocará su método setBeanName(…) pasándole como parámetro el identificador del bean. ¿Quién Soy?: BeanNameAware
  • 101. De la misma forma, accedemos a la factoría y al contexto: publicclassStudentServiceImplimplementsStudentService, ApplicationContextAware { privateApplicationContextcontext; publicvoidsetApplicationContext(ApplicationContextcontext) { this.context = context; } … } ¿De dónde vengo?: BeanFactoryAware & ApplicationContextAware
  • 102. Modificar el piloto 26.0 par que: La clase Malabarista reciba y almacene Contexto La factoría Su nombre Forzar además a que cuando reciba su nombre, muestre un mensaje diciendo: “Hola, me llamo actor” (Resuelto en piloto 27.0) Taller práctico
  • 103. La inyección de dependencias no es la única forma de interacción entre beans en Spring. La otra alternativa es basarse en el modelo de eventos de los JavaBeans. Un beanpublicador dispara un evento que será recibido por todos aquellos que estén registrados como escuchadores. El publicado y los escuchadores (listeners) no se conocen entre sí, están desacoplados. Gestión de Eventos en Spring
  • 104. Es Spring un bean puede ser Publisher Listener Ambos dos. Gestión de Eventos en Spring
  • 105. Un evento para poder ser gestionado por Spring debe extender la clase ApplicationEvent. publicclassCourseFullEventextendsApplicationEvent { privateCoursecourse; publicCourseFullEvent(Objectsource, Coursecourse) { super(source); this.course = course; } publicCoursegetCourse() { returncourse; } } Creación de eventos
  • 106. Una vez creado… ¿Cómo lo publicamos? El objeto ApplicationContext tiene el método publishEvent(), que nos permite publicar instancias de la clase ApplicationEvent. Todo aquel beanApplicationListener registrado en el contenedor recibirá el evento mediante una llamada a su método onApplicationEvent() ApplicationContextcontext = …; Coursecourse = …; context.publishEvent(new CourseFullEvent(this, course)); Problema: Necesitamos hacer que un bean sea capa de procesar eventos. ¿Cómo se hace eso? Publicación de Eventos
  • 107. Para que un bean dado de alta en el contenedor reciba eventos que extiendan la clase ApplicationEvent, deberá implementar la Interfaz ApplicationListener Public interface ApplicationListener { publicvoidonApplicationEvent(ApplicationEventevent); } El contenedor detecta que es listener de los eventos y lo añade automáticamente a la suscripción. Ser Listener
  • 108. Extender el piloto 27 para que: Aparezca una clase Representante y un bean de su tipo declarado en el contendor. Aparezca un evento PaseEvent con un método getActor() que retorne la instancia de Actor que actúa en el Show. El bean Show lance un evento PaseEvent por cada actor que actúe para que el Representante lo escuche y tome nota de cuanto debe facturar al gestor. (Resuelto en el piloto 28.0) Taller práctico
  • 109. El show va a ser retransmitido por televisión, y por lo tanto, es necesario avisar al técnico de control para que cuando termine una actuación importante, pase a publicidad, y cuando comience la siguiente importante, retome la conexión con el escenario. La tele sólo se interesa por las grandes personalidades como Kenny G y Bill Clinton, pero para mantener al público viendo los anuncios, los ponemos al comienzo y fin de espectáculo. Para modelar esto, vamos a necesitar crear dos tipos de eventos diferentes que representen el comienzo y el final de una actuación. En el primero además enviaremos el actor participa en el mismo. Taller práctico
  • 110. Tendremos que: Creamos dos nuevos eventos: ComienzoVIPEvent – con una propiedad Actor FinVIPEvent Modificar la clase Show para que cuando comiencen bill o kenny se dispare el correspondiente evento, así como cuando finalicen. Implementar TecnicoTelevision y dar de alta al bean “urdazi” como tal. Tiene que ser capaz de escuchar eventos de tipo ApplicationEvent, y publicar los mensajes de inicio y fin de la retransmisión, dependiendo del evento que le llegue. Resuelto en piloto 28.5 Taller práctico
  • 111. Spring AOP Programación Orientada a Aspectos
  • 112. Definición de POA Fue presentada en público por Gregor Kickzales y su equipo de investigación de Palo Alto Research Center en 1996. Paradigma de programación relativamente reciente. De esta forma se consigue: Razonar mejor sobre los conceptos. Eliminar la dispersión del código. Implementaciones resultan más comprensibles, adaptables y reusables.
  • 113. Definición de Aspecto “ Un aspecto es una unidad modular que se disemina por la estructura de otras unidades funcionales. Los aspectos existen tanto en la etapa de diseño como en la de implementación. Un aspecto de diseño es una unidad modular del diseño que se entremezcla en la estructura de otras partes del diseño. Un aspecto de programa o de código es una unidad modular del programa que aparece en otras unidades modulares del programa (G. Kiczales) ”
  • 114. Definición de Aspecto Los aspectos son la unidad básica de la POA, y pueden definirse como las partes de una aplicación que describen las cuestiones claves relacionadas con la semántica esencial o el rendimiento. También pueden verse como los elementos que se diseminan por todo el código y que son difíciles de describir localmente con respecto a otros componentes. Ej.: patrones de acceso a memoria, sincronización de procesos concurrentes, manejo de errores, etc.
  • 115. Estructura de un Programa OA
  • 116. Estructura de un Programa OA Se muestra un programa como un todo formado por un conjunto de aspectos más un modelo de objetos. Con el modelo de objetos se objetos se recoge la funcionalidad de negocio. Los aspectos recogen características de rendimiento, infraestructura y otras no relacionadas con el modelo de negocio.
  • 117. Objetivos Fundamentales de la POA Extraer y centralizar en un solo punto los "crosscuttingconcepts“  cada decisión se toma en un lugar concreto y no diseminada por la aplicación. Minimizar las dependencias entre ellos  desacoplar los distintos elementos que intervienen en un programa.
  • 118. Objetivos Fundamentales de la POA Idea principal es centralizar en un solo punto todos los aspectos comunes a las clases que forman el sistema software. Figura 1. Evolución de un sistema OO a uno OA
  • 119. Ventajas de la POA Un código menos enmarañado, más natural y más reducido. Mayor facilidad para razonar sobre los conceptos, ya que están separados y las dependencias entre ellos son mínimas. Un código más fácil de depurar y más fácil de mantener.
  • 120. Ventajas de la POA Se consigue que un conjunto grande de modificaciones en la definición de una materia tenga un impacto mínimo en las otras. Se tiene un código más reusable y que se puede acoplar y desacoplar cuando sea necesario.
  • 122. Conceptos Básicos de POA Aspecto
  • 124. Consideraciones Importantes La POA no rompe con las técnicas de programación orientadas a objetos sino que las complementa y extiende. El nuevo paradigma de la programación orientada a aspectos es soportado por los llamados lenguajes de aspectos, que proporcionan constructores para capturar los elementos que se diseminan por todo el sistema.
  • 125.
  • 126. Uno o varios lenguajes de aspectos. El lenguaje de aspectos define la forma de los aspectos, por ejemplo, los aspectos de AspectJ se programan de forma muy parecida a las clases.
  • 127. Un tejedor de aspectos. Fundamentos de la POA
  • 128.
  • 129.
  • 130. Estructura de una implementación en los lenguajes tradicionales. Implementación en Lenguajes
  • 131. Implementación en lenguajes Estructura de una implementación en los lenguajes de aspectos.
  • 132. Los aspectos son tejidos en los objetos objetivo en los puntos de enlazado especificados (joinpoints). Puede ser en tres momentos de la vida del objeto: Tiempo de compilación – El código fuente del objetivo es enriquecido con el código de los aspectos en los joinpoints, y luego compilado. Así trabaja AspectJ Durante la carga de clases – Los aspectos se enlazan en el momento de la carga de clases. Se requiere un ClassLoader especial. En tiempo de ejecución – Aplicando el patrón Proxy, se intercepta la petición y se delega en los aspectos cuando se requiere. Spring AOP trabaja de esta forma. Tipos de enlazado (Weaving)
  • 133. Los advices en Spring están escritos en Java Podemos usar IDEs corrientes Conocemos el lenguaje Los pointcuts se declaran en un fichero XML Estándar conocido. AspectJ requiere una sintaxis especial. Spring realiza el tejido de aspectos en tiempo de ejecución, sirviéndose del patrón Proxy. ¿Qué nos permite Spring AOP?Soporte de Spring
  • 134. La ejecución el objeto “acosejado” por el aspecto es interceptada por un objeto Proxy que realiza las labores definidas en el pointcut. Los proxies serán creados por el ApplicationContext cuando carga los beans declarados en el contenedor. Dado que se crean en tiempo de ejecución, no se necesita ningún compilador específico para AOP con Spring. Funcionamiento de Spring AOP
  • 135. Dos tipos: La clase aspectizada implementa un interfaz que contiene los métodos por los que se van a realizar los pointcuts Spring usa la java.lang.reflect.Proxy para generar automáticamente una nueva clase que implementa la ineterfaz, teje los aspectos e intercepta toda llamada a esos métodos de la interfaz. La clase es un POJO. Spring usa CGLIB para generar un proxy a medida en tiempo de compilación, extendiendo la clase objetivo (por lo que no podemos usar métodos final.) Tipos de intercepción
  • 136. Spring implementa las interfaces de AOP Alliance: Acuerdo para promover un uso estandarizado de la AOP independientemente de la tecnología (Java) subyacente sobre la que se generen los aspectos. Un aspecto creado con estos interfaces es portable a otras plataformas AOP AOP Alliance Interfaces
  • 137. Spring sólo soporta MethodJoinpoints Otras plataformas (AspectJ, Aspect JBOSS) soportan fieldjoinpoints, lo que permite aspectos más refinados. No obstante, si todos los accesos a atributos se realizan por medio de los métodos accessor, se pueden emular los efectos. Puntos de unión en Spring
  • 139. Vamos a probar los aspectos extendiendo el Espectáculo que ya tenemos funcionando, haciendo que aparezca un nuevo actor: el público. Antes de nada, bajamos de la zona de descargas el jar de la CGLIB y lo añadimos en lib y al classpath del proyecto actual. Creamos una clase Audiencia con los siguientes métodos, y la declaramos como el beanaudiencia en el beans.xml: Mi primer aspecto
  • 140. Ahora... ¿Quién invoca a la clase audiencia? El público no va dirigido ni por el actor de turno, ni por el propio espectáculo, sino que responden a situaciones automáticamente. Vamos a crear un aspecto para que dispare los métodos del bean audiencia antes y después de cada actuación de un actor. Mi primer aspecto
  • 141. Creamos una nueva clase Java es.uniovi.si.aop.AudienciaAdvice, de forma que: Implemente: AfterReturningAdvice MethodBeforeAdvice ThrowsAdvice Tenga una propiedad audiencia para poder obtener una referencia a la misma por inyección. Implementamos los tres métodos, invocando a los métodos de audiencia que corresponda en cada contexto. Implementando el aspecto
  • 142. Una vez creada la clase AudiencieAdvise, damos de alta el beanaudiencieAdvice inyectando la audiencia como propiedad. Ahora tenemos que definir el punto de corte. Con el punto de corte le diremos a Spring donde exactamente queremos aplicar el advice que hemos implementado. Spring permite utilizar varios tipos de puntos de corte. Implementando el aspecto
  • 143. Objetivo: seleccionar los métodos sobre los que aplicar el advise. Solución: Aplicación de un patrón de expresiones regulares sobre la signatura de los métodos Spring incorpora dos clases que implementan estos puntos de corte: org.springframework.aop.support.Perl5RegexpMethodPointcut (Requiere Jakarta ORO) org.springframework.aop.support.JdkRegexpMethodPointcut (Usa el RegExp incorporado en Java 1.4) Declarando un punto de corte con expresiones regulares.
  • 144. Para utilizar el punto de corte, primero tenemos que declararlo como bean en el contenedor: <bean id=“actuacionPointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut"> <property name="pattern" value=".*actua" /> </bean> Este patrón encaja con cualquier método que se llame actua. Declarando un punto de corte con expresiones regulares.
  • 145. Ahora tenemos que asociar el punto de corte con el advice: <bean id="audienciaAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"> <property name="advice" ref="audienciaAdvice" /> <property name="pointcut" ref="actuacionPointcut" /> </bean> Con esto ya tenemos el aspecto completo implementado. Para que funcione, nos falta un último paso, la creación de los objetos proxy de los beans que queremos “aspectizar” Asociando pointcut y advice
  • 146. Para todo bean “aconsejado” por un advisor, es necesario crear un proxy. El proxy es el que realmente actuará cuando el advisor haga su trabajo, y por lo tanto, es el que realmente debemos “cablear”. Para crear un proxy para el kenny, por ejemplo: Creación de los Proxies
  • 147. <bean id="kenny" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="kennyTarget" /> <property name="interceptorNames" value="audienciaAdvisor" /> <propertyname="proxyInterfaces” value="es.uniovi.si.Actor" /> </bean> <bean id="kennyTarget" parent="Saxofonista"> <property name="nombre" value="Kenny G" /> <property name="telefono" value="0034-650423942-00" /> <lookup-methodname="getInstrumento" bean="fender" /> </bean> Creamos los proxies para el resto de los actores y ya podemos ejecutar la aplicación. (Resuelto en Piltoto 29.0) Creación del proxy para los beansaspectizados
  • 148. Modificar el piloto 29.0 para que la guitarra dispare irremisiblemente una excepción de tipo Runtime() y comprobar que el público pide su devolución. (Resuelto en piloto 30.0) Taller práctico
  • 149. La organización del espectáculo está preocupada por los controles de inmigración que la seguridad social está realizando sin previo aviso, así que decide poner un vigilante que, antes de cada actuación, le pida las credenciales a los artistas para dejarles trabajar o no. Tendremos que seguir los siguientes pasos... Taller práctico – El vigilante de seguridad
  • 150. Añadir a Actor un método getCredenciales que retorne un boolean (indicando si las tiene o no). Creamos es.uniovi.si.VigilanteAdvise para que implemente BeforeAdvise, y lo damos de alta como vigilanteAdvise. Implementamos el método before para que muestre un mensaje indicando si el target (tercer parámetro del método) tiene o no credenciales. El punto de corte... Ya lo tenemos declarado! Será el mismo que para el ejemplo anterior Asociamos el nuevo advisor con el punto de corte mediante el pointcutadvisorvigilanteAdvisor. Finalmente, en el proxy, forzamos a que tenga en cuenta ambos interceptores: <property name="interceptorNames" value="audienciaAdvisor,vigilanteAdvisor" /> Resuelto en piloto 31.0 Taller práctico – El vigilante de seguridad
  • 151. A partir del piloto 31.0, modificarlo para que: el malabarista no tenga credenciales El vigilante lance una excepción de tipo InmigranteIlegalExcepcion avisando de que no puede trabajar. Ejecutarlo ¿Qué ha ocurrido? ¿Dónde deberíamos capturar la excepción para que la aplicación siga funcionando? Capturarla en el lugar adecuado y mostrar un mensaje de la organización explicando la cancelación de la actuación. (Resuelto en piloto 32.0) Taller práctico – Probando al vigilante
  • 153. Vamos a comenzar la implementación de una infraestructura base basada en Spring para el desarrollo de aplicaciones. Desarrollaremos el esqueleto de una aplicación modelo sirviéndonos de Spring para ahorrarnos código que solemos tener que implementar para cada aplicación. Aplicando Spring
  • 154. Partir del último piloto manipulado y: Eliminar todas las clases menos la factoría Dejar el beans.xml sin ningún bean para poder empezar de cero. Vamos a partir de un entorno vacío sobre el cual trabajar. Implementar la clase Main con método main y método comienzo. El main obtendrá una referencia a sí mismo por medio de la factoría e invocará su método comienzo. Primer paso: Preparando el entorno
  • 155. Queremos desarrollar un menú configurable que valga para cualquier aplicación de ventanas. Cada elemento del menú (MenuItem) contendrá una descripción (description) y uno o varios subelementos, que serán inyectados por Spring. Configurarlo para que de momento tenga la siguiente estructura: Desarrollando el menú
  • 156. Desarrollo del menú Finalmente, implementar un método printMenu en la clase Main que pinte tabuladamente las diferentes opciones del menú invocando el toString() de muniItem. (Resuelto en piloto 40.0)
  • 157. Vamos a aplicar el patrón command. Para ello: Implementaremos un interface es.uniovi.si.menu.MenuCommand que contenga un método execute. Prepararemos el MenuItem para que: Pueda recibir uno o varios Command por inyección, y los invoque en orden de inyección en un método run Creamos un comando (ejemplo, es.uniovi.si.comandos.AbrirCommand) para cada opción final del menú que de momento sólo mostrará un mensaje cuando se invoque, y los inyectamos en su correspondiente opción del menú. (Resuelto piloto 41.0) Inyectando lógica en el menú
  • 158. Añadir a MenuItem una propuedadbooleanactive SIN INICIALIZAR, y modificarlo para que si vale false, el ´nombre del menú aparezca entre * al llamar al toString(). Ej: *Abrir* Crear los eventos: es.uniovi.si.menu.event.AuthorizeMenuItemsEvent es.uniovi.si.menu.event.DenyMenuItemsEvent es.uniovi.si.menu.event.AuthorizeAllMenuItemsEvent es.uniovi.si.menu.event.DenyAllMenuItemsEvent de forma que los dos primeros contengan una colección con los ids (tal y como han sido asignados en el beans.xml) de los menús a activar o desactivar. Crear una clase MenuController, que implemente los métodos autorizeMenuItems(…) denyMenuItems(…) authorizeAll() denyAll() de forma que se sirva de los eventos para activar o desactivar las opciones del menú que le soliciten cambiar. Las dos primeras podrán recibir uno o varios ids de tipo String. Lo instanciamos como el bean “menuController” y se lo inyectamos a Main Activando y desactivando menús
  • 159. Configurar el menú para que por defecto, todos los menús estén activos (¿uno a uno?), y cambiar lo necesario para que el menú pegar aparezca desactivado. Para probarlo, modificar el método comienzo de Main para que: Pinte el menú Desactive el menú de cortar Pinte el menú Active todas las opciones Pinte el menú (Resuelto en piloto 42.0) Activando y desactivando menús
  • 160. A estas alturas, decidimos que el no tiene sentido que Main contenga directamente el menú ni que implemente el método printMenu(). Refactorizamos la aplicación para que sea el MenúController el que contenga ambos elementos, de forma que el Main sólo interactúe con el menúController. (Resuelto en piloto 43.0) Refactorizando
  • 161. Añadir un servicio de log tal que: La interfaz de acceso sea es.uniovi.si.infraestructura.log.Log y tenga los métodos: log warn error fatalError La clase que lo implemente sea es.uniovi.si.infraestructura.log.MiLog La clase Main tenga acceso al log y muestre un mensaje para corroborar que funciona. Servicio de Log
  • 162. Implementamos el LogAdvice para que: Al entrar trace un mensaje notificando que se ha invocado el método X de la clase Y con los argumentos Z Al salir muestre un mensaje notificando el final del método X de la clase Y retornando Z Al capturar una excepción notifique un error. Creamos la interfaz MenuItemInterface, dado que para interceptar las invocaciones el advice requiere un interfaz (que luego implementará el Proxy). Ahora el MenuItemcontendrá elementos de tipo MenuItemInterface (lo hace solo eclipse!) Creamos el pointcut para que capture invocaciones a los métodos run de los menús Modificar el printMenu para que invoque cada método run. AspectizamosmenuAbriry probamos. (Resuelto en piloto 44.0) Aspectizando el log
  • 163. Implementamos ahora un aspecto materializado en es.uniovi.si.infraestructura.security.SecurityAdvice de forma que: Reciba un objeto de tipo User en un atributo usuario con un método getUser que retorne el id del usuario. Reciba un String[] con los usuarios autorizados a ejecutar la aplicación Prepararlo para que antes de la invocación del método interceptado compruebe que el usuario tiene permisos para usar la aplicación Se dispare antes de cada comando del menú La clase Main inicializará el beanUser antes de invocar la impresión del menú. (Resuelto en trabajo 45.0) Aspecto de seguridad