UNIDAD 4: El framework Spring
eugeniaperez.es
eugeniaperez.es
4.2 Características de Spring
Entorno de desarrollo
Estamos creando un proyecto ordinario en Spring con la estructura de Maven. Incluirá el pom con sus dependencias
eugeniaperez.es
4.2 Características de Spring
Entorno de desarrollo
Para la configuración de Spring: beans.xml que se almacena en src/main/resources. Para generarlo:
New > Other > Spring > Spring Bean Configuration File
Debemos especificar los espacios de nombres XSD
Y ya está listo para introducir beans!
eugeniaperez.es
4.2 Características de Spring
Inyección de dependencias (ID)
eugeniaperez.es
4.2 Características de Spring (ID)
Inyección de dependencias (ID)
public class Mensajero {
private Furgoneta vehiculo = new Furgoneta();
public Mensajero () {
}
public void desplazarse () {
vehiculo.moverse();
}
}
eugeniaperez.es
4.2 Características de Spring (ID)
Inyección de dependencias (ID)
Usando ID esas dependencias se asignarán desde fuera.
Hay dos formas básicas de hacerlo: constructor o set.
Además usando una interfaz se facilitan:
poder meter distintos tipos de vehículo (que deben implementar ese interfaz)
simplificar el testeo del método desplazarse.
eugeniaperez.es
4.2 Características de Spring (ID)
Inyección de dependencias (ID)
eugeniaperez.es
public interface Vehiculo {
public void moverse();
}
public class Furgoneta implements Vehiculo {
private int deposito;
public void moverse() {
if (deposito > 0)
deposito--;
}
}
Programando por contratos...
4.2 Características de Spring (ID)
Inyección de dependencias (ID)
eugeniaperez.es
public class Mensajero {
private Vehiculo vehiculo;
public Mensajero (Vehiculo vehiculo) {
this.vehiculo = vehiculo;
}
public void desplazarse () {
vehiculo.moverse();
}
}
El vehículo, de cualquier tipo que implemente esa interfaz, se asignará desde fuera, en el XML de Spring.
Testear el método desplazarse fácilmente
4.2 Características de Spring (ID)
Inyección de dependencias (ID)
Comprobando que realmente se llama al método moverse():
import static org.mockito.Mockito.*;
import org.junit.Test;
public class MensajeroTest {
@Test
public void desplazarseLlamaAMoverse () {
// Creamos el mock para las pruebas
Vehiculo vehiculoFalso = mock(Vehiculo.class);
// Inyectamos esa instancia para la prueba
Mensajero mensajero = new Mensajero(vehiculoFalso);
mensajero.desplazarse();
// AHORA SÍ, podemos verificar si se llama a moverse una vez (junit)
verify(vehiculoFalso, times(1)).moverse();
}
}
Lo ideal es probar lo que sale fuera: los métodos públicos: La interfaz!!
eugeniaperez.es
4.2 Características de Spring
Inyección de dependencias (ID)
eugeniaperez.es
4.2 Características de Spring
Inyección de dependencias (ID)
public class Person {
private long id;
private String name;
private Address address;
//Getters, setters & toString()
}
public class Address {
private long id;
private String street;
private String postCode;
//Getters, setters & toString()
}
eugeniaperez.es
4.2 Características de Spring
Inyección de dependencias (ID) - Mediante set
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd ">
<bean id="address" class="org.sistema.spring.dependencyInjection.models.Address">
<property name="id" value="1" />
<property name="street" value="Avenida Barañáin" />
<property name="postCode" value="31000" />
</bean>
<bean id="person" class="org.sistema.spring.dependencyInjection.models.Person">
<property name="id" value="1" />
<property name="name" value="Eugenia" />
<property name="address" ref="address" />
</bean>
</beans>
eugeniaperez.es
4.2 Características de Spring
Inyección de dependencias (ID) - Mediante set
Address address = new Address();
address.setId(1);
address.setStreet("Avenida Barañáin");
address.setPostCode("31000");
Person person = new Person();
person.setId(1);
person.setName("Eugenia");
person.setAddress(address);
eugeniaperez.es
4.2 Características de Spring
Inyección de dependencias (ID) - Mediante set
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd ">
<bean id="address" class="org.sistema.spring.dependencyInjection.models.Address"
p:id="1" p:street="Avenida Barañáin" p:postCode="31000" />
<bean id="person" class="org.sistema.spring.dependencyInjection.models.Person"
p:id="1" p:name="Eugenia" p:address-ref="address" />
</beans>
eugeniaperez.es
4.2 Características de Spring
Inyección de dependencias (ID) - Mediante constructor
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<bean id="address" class="com.sistema.spring.Address">
<constructor-arg name="id" value="1" />
<constructor-arg name="street" value="Avenida Barañáin" />
<constructor-arg name="postCode" value="31000" />
</bean>
<bean id="person" class="com.sistema.spring.Person">
<constructor-arg name="id" value="1" />
<constructor-arg name="name" value="Eugenia" />
<constructor-arg name="address" ref="address" />
</bean>
</beans>
eugeniaperez.es
4.2 Características de Spring
Inyección de dependencias (ID) - Mediante constructor
Address address = new Address(1, "Avenida Barañáin", "31000");
Person person = new Person(1, "Eugenia", address);
Necesitarás un constructor en cada clase que reciba todos esos parámetros y, adicionalmente, su constructor por defecto.
eugeniaperez.es
4.2 Características de Spring
Inyección de dependencias (ID)
eugeniaperez.es
4.2 Características de Spring
Inyección de dependencias (ID)
public class Main {
private static ApplicationContext context;
public static void main(String[] args) {
context = new ClassPathXmlApplicationContext("beans.xml");
Person person = (Person) context.getBean("person");
System.out.print(person);
}
}
Person [id=1, name=Eugenia, address=Address [id=1, street=Avenida Barañáin, postCode=31000]]
eugeniaperez.es
Descarga el código en Bitbucket
Descarga el proyecto spring.dependencyinjection del repositorio de Bitbucket:
Usuario:
Psswd:
https://eugenia_perez@bitbucket.org/eugenia_perez/spring.dependencyinjection.git
eugeniaperez.es
4.2 Características de Spring
Autowiring
eugeniaperez.es
4.2 Características de Spring
SIN autowiring
<bean id="customer" class="com.sistema.common.Customer">
<property name="person" ref="person" />
</bean>
<bean id="person" class="com.sistema.common.Person" />
<bean id="customer" class="com.sistema.common.Customer" autowire="byName" />
<bean id="person" class="com.sistema.common.Person" />
CON autowiring
eugeniaperez.es
4.2 Características de Spring
El proyecto javamon consiste en una clase combate que carga dos instancias de la clase Javamon (por autowiring) y las hace pelear. Todo ello se maneja desde una clase principal.
eugeniaperez.es
Descarga el código en Bitbucket
Descarga el proyecto spring.autowiring del repositorio de Bitbucket:
Usuario:
Psswd:
URL: https://eugenia_perez@bitbucket.org/eugenia_perez/spring.autowiring.git
eugeniaperez.es
4.2 Características de Spring
El método Main:
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
"beans.xml");
Combat combat = (Combat) context.getBean("combat");
combat.combat();
System.out.println("And the winner is: " + combat.outcome().getName());
System.out.println("Thanks for playing javamon");
}
}
eugeniaperez.es
4.2 Características de Spring
Creamos dos beans llamados estratégicamente javamon1 y javamon2 que DEBEN COINCIDIR con los nombres de los atributos de la clase Combat. En la instancia de combat debemos decir que hacemos autowiring, y spring hilará el resto
<bean id="javamon1" class="org.sistema.spring.autowiring.models.Javamon">
<constructor-arg value="Pikachu" />
</bean>
<bean id="javamon2" class="org.sistema.spring.autowiring.models.Javamon">
<constructor-arg value="Bulbasur" />
</bean>
<bean id="combat" class="org.sistema.spring.autowiring.models.Combat"
autowire="byName">
eugeniaperez.es
4.2 Características de Spring
Autowiring con anotaciones
También es posible la DI mediante anotaciones en las propias clases (@Autowired).
Y añadiendo en el beans.xml el espacio de nombres de context y la etiqueta: <context:annotation-config/>
eugeniaperez.es
4.2 Características de Spring
Autowiring con anotaciones
El proyecto consiste una serie de clases que representan las clases de un partido de fútbol.
eugeniaperez.es
Descarga el código en Bitbucket
Descarga el proyecto spring.autowiringannotations del repositorio de Bitbucket:
Usuario:
Psswd:
URL: https://eugenia_perez@bitbucket.org/eugenia_perez/spring.autowiringannotations.git
eugeniaperez.es
4.3 Spel
eugeniaperez.es
4.3 Spel
La expresión más simple de SpEL es un valor dentro de #{}:
También podríamos mostrar una propiedad de un bean:
<property name=”speed” value=”#{140}” />
<property name=”description” value=”Your age is #{84}” />
<property name=”street2” value=”#{'address.street'}” />
<property name=”streets” value=”#{'streets[2]'}” />
O una colección...
eugeniaperez.es
4.3 Spel
Mediante el operador T() tenemos acceso a atributos y métodos estáticos de las clases:
También se puede hacer de esta otra forma usando pseudojava y operaciones aritméticas como se ve en el ejemplo anterior:
<property name=”strength” value=”#{T(java.lang.Math).PI}” />
<property name=”strength” value=”#{T(java.lang.Math).random()}” />
#{new java.util.Random().nextInt(6) + 1}
eugeniaperez.es
4.3 Spel
Operaciones aritméticas (+, -, * , /, %, ^):
Operaciones de comparación (<,>,==,<=, >=, lt, gt, eq, le, ge):
Operaciones lógicas (and, or, not, !):
Operaciones condicionales y ternaria (?):
<property name=”area” value=”#{T(java.lang.Math).PI * 40 ^2}” />
<property name=”isAllowed” value=”#{customer1.age > 17}” />
<property name=”isHero” value=”#{player1.speed > 100 and player1.level >19}” />
<property name=”weapon” value=”#{player1.fight()?axe:sword}” />
eugeniaperez.es
4.4 Spring JDBC
eugeniaperez.es
Descarga el código en Bitbucket
Descarga el proyecto spring.jdbc del repositorio de Bitbucket:
Usuario:
Psswd:
URL: https://eugenia_perez@bitbucket.org/eugenia_perez/spring.jdbc.git