Spring framework 5 : Definiendo un perfil por defecto


En el post anterior aprendimos como crear e utilizar perfiles utilizando spring, ahora toca el turno de aprender como definir un perfil por defecto.

Definiendo los servicios a utilizar

/**
 * 
 * @author raidentrance
 *
 */
public interface EnvironmentService {

	String getEnvironmentName();

}
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

/**
 * @author raidentrance
 *
 */
@Service
@Profile({"dev","default"})
public class DevEnvironmentService implements EnvironmentService {
	
	@Override
	public String getEnvironmentName(){
		return "dev";
	}
	
}
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

/**
 * @author raidentrance
 *
 */
@Service
@Profile("qa")
public class QaEnvironmentService implements EnvironmentService {

	@Override
	public String getEnvironmentName() {
		return "qa";
	}

}
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

/**
 * @author raidentrance
 *
 */
@Service
@Profile("prod")
public class ProdEnvironmentService implements EnvironmentService{

	@Override
	public String getEnvironmentName() {
		return "prod";
	}

}

Como vemos tenemos una interfaz llamada EnvironmentService.java la cual cuenta con 3 implementaciones DevEnvironmentService.java, QaEnvironmentService.java y ProdEnvironmentService.java, estos servicios están anotados con @Profile indicando el perfil de acuerdo al cual se crearán.

Solo tenemos una particularidad en la clase DevEnvironmentService podemos ver que la anotación se ve del siguiente modo:

.....
@Profile({"dev","default"})
public class DevEnvironmentService implements EnvironmentService {
...

Esto significa que el bean se activará con el perfil de dev o si no se especifica ningún otro perfil.

Ejecutando la aplicación

Para probar la aplicación ejecutaremos la siguiente clase:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

import com.devs4j.datasource.EnvironmentService;

@SpringBootApplication
public class SpringExampleApplication {

	public static void main(String[] args) {
		ConfigurableApplicationContext applicationContext = SpringApplication.run(SpringExampleApplication.class, args);
		EnvironmentService service = applicationContext.getBean(EnvironmentService.class);
		System.out.printf("Active environment %s \n", service.getEnvironmentName());
	}

}

Como podemos ver no especificamos ningún perfil en el archivo application.properties, y a pesar de eso al ejecutar nuestra aplicación veremos la siguiente salida:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.2.RELEASE)

2019-01-30 21:58:20.406  INFO 16889 --- [           main] com.devs4j.SpringExampleApplication      : Starting SpringExampleApplication on MacBook-Pro-de-Alejandro.local with PID 16889 (/Users/raidentrance/Documents/workspace-sts-3.8.3.RELEASE/spring-example/target/classes started by raidentrance in /Users/raidentrance/Documents/workspace-sts-3.8.3.RELEASE/spring-example)
2019-01-30 21:58:20.409  INFO 16889 --- [           main] com.devs4j.SpringExampleApplication      : No active profile set, falling back to default profiles: default
2019-01-30 21:58:21.069  INFO 16889 --- [           main] com.devs4j.SpringExampleApplication      : Started SpringExampleApplication in 1.04 seconds (JVM running for 1.438)
Active environment dev 

Esto nos muestra que el perfil que se activó fue el perfil por defecto.

Para estar al pendiente sobre nuestro contenido nuevo síguenos en nuestras redes sociales  https://www.facebook.com/devs4j/ y https://twitter.com/devs4j.

Autor: Alejandro Agapito Bautista
Twitter: @raidentrance
Contacto:raidentrance@gmail.com

Spring framework 5 : Uso de perfiles en Spring


Cuando trabajamos con Spring framework nos encontraremos con momentos en los que tenemos que activar o desactivar beans de acuerdo a ciertas circunstancias, por ejemplo diferentes ambientes utilizan diferentes bases de datos, diferentes países utilizan diferentes idiomas, etc.

Definición de servicios

Para mostrar el funcionamiento de los perfiles en Spring crearemos los siguientes servicios de spring de ejemplo:

/**
 * 
 * @author raidentrance
 *
 */
public interface EnvironmentService {

	String getEnvironmentName();

}
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

/**
 * @author raidentrance
 *
 */
@Service
@Profile("dev")
public class DevEnvironmentService implements EnvironmentService {
	
	@Override
	public String getEnvironmentName(){
		return "dev";
	}
	
}
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

/**
 * @author raidentrance
 *
 */
@Service
@Profile("qa")
public class QaEnvironmentService implements EnvironmentService {

	@Override
	public String getEnvironmentName() {
		return "qa";
	}

}

import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

/**
 * @author raidentrance
 *
 */
@Service
@Profile("prod")
public class ProdEnvironmentService implements EnvironmentService{

	@Override
	public String getEnvironmentName() {
		return "prod";
	}

}

Como vemos tenemos una interfaz llamada EnvironmentService.java la cual cuenta con 3 implementaciones DevEnvironmentService.java, QaEnvironmentService.java y ProdEnvironmentService.java, estos servicios están anotados con @Profile indicando el perfil de acuerdo al cual se crearán.

Utilizando el Bean

Una vez que se definieron los beans el siguiente paso será utilizarlos, para esto utilizaremos el siguiente código:


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

import com.devs4j.datasource.EnvironmentService;

@SpringBootApplication
public class SpringExampleApplication {

	public static void main(String[] args) {
		ConfigurableApplicationContext applicationContext = SpringApplication.run(SpringExampleApplication.class, args);
		EnvironmentService service = applicationContext.getBean(EnvironmentService.class);
		System.out.printf("Active environment %s \n", service.getEnvironmentName());
	}

}

Al ejecutar el código anterior tendremos la siguiente salida:

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.devs4j.datasource.EnvironmentService' available

Como vemos el error nos dice que no asignamos un qualifier al obtener la referencia de EnvironmentService, en lugar de hacerlo lo que haremos será definir un perfil de spring.

Definiendo el perfil

Como recordamos del primer post https://devs4j.com/2019/01/29/spring-framework-5-creando-un-proyecto-de-spring/ existe un archivo llamado application.properties, en el cual podremos definir el perfil bajo el cual se ejecutará nuestra aplicación, para hacerlo le agregaremos la siguiente línea:

application.properties

spring.profiles.active=dev

La línea anterior indica que el perfil que se activará será el perfil de desarrollo, una vez hecho esto ejecutaremos de nuevo nuestra aplicación y veremos lo siguiente:

2019-01-30 21:23:47.416  INFO 16798 --- [           main] com.devs4j.SpringExampleApplication      : Starting SpringExampleApplication on MacBook-Pro-de-Alejandro.local with PID 16798 (/Users/raidentrance/Documents/workspace-sts-3.8.3.RELEASE/spring-example/target/classes started by raidentrance in /Users/raidentrance/Documents/workspace-sts-3.8.3.RELEASE/spring-example)
2019-01-30 21:23:47.423  INFO 16798 --- [           main] com.devs4j.SpringExampleApplication      : The following profiles are active: dev
2019-01-30 21:23:48.158  INFO 16798 --- [           main] com.devs4j.SpringExampleApplication      : Started SpringExampleApplication in 1.253 seconds (JVM running for 1.641)
Active environment dev 

Como vemos el perfil se activó correctamente y al final nos imprime Active environment dev.

¿Qué pasa si inyecto el bean utilizando su implementación?

Como vimos activamos el perfil de dev y por esto al obtener una referencia de tipo EnvironmentService.java obtuvimos una de tipo DevEnvironmentService.java, pero, ¿Qué pasa si hacemos lo siguiente? :

ProdEnvironmentService prodService = applicationContext.getBean(ProdEnvironmentService.class);

Como vemos el perfil activo es dev, pero estamos tratando de obtener el bean del tipo ProdEnvironmentService.java. Al hacerlo nos podemos dar cuenta que obtendremos el siguiente error:

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.devs4j.datasource.ProdEnvironmentService' available

Esto es debido a que el bean no se creó por spring y no se agregó al contexto dado que no tiene el perfil indicado.

Para estar al pendiente sobre nuestro contenido nuevo síguenos en nuestras redes sociales  https://www.facebook.com/devs4j/ y https://twitter.com/devs4j.

Autor: Alejandro Agapito Bautista
Twitter: @raidentrance
Contacto:raidentrance@gmail.com

Spring framework 5 : Uso de la anotación @Primary


En el ejemplo anterior vimos como utilizar la anotación @Qualifier y como nos ayuda cuando tenemos multiples implementaciones de una interfaz. El problema de esa solución es cuando se utiliza @Autowired sin especificar el qualifier dado que Spring falla con el siguiente error:

Field userService in com.devs4j.qualifier.UserController required a single bean, but 2 were found

Esto se resuelve fácilmente utilizando un qualifier o utilizando la anotación @Primary, esta anotación nos permite indicar el bean default a inyectar en caso de que no se especifique ningún qualifier, veamos el siguiente ejemplo:

UserService.java


/**
 * @author raidentrance
 *
 */
public interface UserService {

	public boolean authenticate(String username, String password);
}

UserServiceDatabaseImpl.java


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

/**
 * @author raidentrance
 *
 */
@Service
@Primary
public class UserServiceDatabaseImpl implements UserService {

	private static Logger log = LoggerFactory.getLogger(UserServiceDatabaseImpl.class);
	

	@Override
	public boolean authenticate(String username, String password) {
		log.info("authenticating against the database");
		return false;
	}

}

UserServiceActiveDirectoryImpl.java


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

/**
 * @author raidentrance
 *
 */
@Service
public class UserServiceActiveDirectoryImpl implements UserService {

	private static Logger log = LoggerFactory.getLogger(UserServiceActiveDirectoryImpl.class);

	@Override
	public boolean authenticate(String username, String password) {
		log.info("authenticating against the active directory ");
		return false;
	}

}

Como podemos ver tenemos las siguientes clases:

  • UserService : Interfaz que cuenta con 2 implementaciones
  • UserServiceDatabaseImpl : Implementación de UserService que utiliza la anotación @Primary
  • UserServiceActiveDirectoryImpl : Implementación de UserService

Una vez que definimos nuestra interfaz y sus implementaciones el siguiente paso será utilizarlo en otro bean, veamos el bean UserController :

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

/**
 * @author raidentrance
 *
 */
@Controller
public class UserController {
	
	@Autowired
	private  UserService userService;
	
	public boolean authenticate(String username, String password) {
		return userService.authenticate(username, password);
	}
}

Como podemos ver es posible inyectar UserService sin especificar ningún qualifier sin recibir ningún error, esto es gracias a que definimos la anotación @Primary en la clase UserServiceDatabaseImpl.

Para estar al pendiente sobre nuestro contenido nuevo síguenos en nuestras redes sociales  https://www.facebook.com/devs4j/ y https://twitter.com/devs4j.

Autor: Alejandro Agapito Bautista
Twitter: @raidentrance
Contacto:raidentrance@gmail.com

Spring framework 5 : Uso de la anotación @Qualifier


En el post anterior vimos como utilizar dependency injection Spring framework 5 : Dependency Injection utilizando Spring ahora es turno de analizar el uso de la anotación @Qualifier y como nos ayuda al momento de utilizar Spring framework.

Definiendo los servicios de spring

En el post anterior vimos como funciona Dependency Injection y como utilizarlo entre diferentes Beans, ahora veamos el siguiente problema para entender el funcionamiento de la anotación @Qualifier :

/**
 * @author raidentrance
 *
 */
public interface UserService {

	public boolean authenticate(String username, String password);
}

Como vemos tenemos una interfaz llamada User service con el método authenticate el cual recibe username y password y devuelve un boolean indicando si se logro autenticar exitosamente.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

/**
 * @author raidentrance
 *
 */
@Service
public class UserServiceDatabaseImpl implements UserService {

	private static Logger log = LoggerFactory.getLogger(UserServiceDatabaseImpl.class);
	

	@Override
	public boolean authenticate(String username, String password) {
		log.info("authenticating against the database");
		return false;
	}

}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

/**
 * @author raidentrance
 *
 */
@Service
public class UserServiceActiveDirectoryImpl implements UserService {

	private static Logger log = LoggerFactory.getLogger(UserServiceActiveDirectoryImpl.class);

	@Override
	public boolean authenticate(String username, String password) {
		log.info("authenticating against the active directory ");
		return false;
	}

}

Ahora podemos ver que se tienen 2 implementaciones, una llamada UserServiceDatabaseImpl.java y la otra UserServiceActiveDirectoryImpl.java una puede autenticar utilizando una base de datos y la otra a través de active directory, para este ejemplo simplemente escribiremos en el log para no sobre complicar el ejemplo.

Utilizando los servicios de spring

Una vez que tenemos los dos servicios definidos el siguiente paso será utilizarlos, veamos la siguiente implementación:


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

/**
 * @author raidentrance
 *
 */
@Controller
public class UserController {
	
	@Autowired
	private  UserService userService;
	
	public boolean authenticate(String username, String password) {
		return userService.authenticate(username, password);
	}
}

Si ejecutamos la aplicación utilizando la implementación de UserController anterior tendremos el siguiente error:

Field userService in com.devs4j.qualifier.UserController required a single bean, but 2 were found:
	- userServiceActiveDirectoryImpl: defined in file [/Users/maagapi/Documents/workspaces/devs4j/devs4j-spring-core/target/classes/com/devs4j/qualifier/UserServiceActiveDirectoryImpl.class]
	- userServiceDatabaseImpl: defined in file [/Users/maagapi/Documents/workspaces/devs4j/devs4j-spring-core/target/classes/com/devs4j/qualifier/UserServiceDatabaseImpl.class]

Esto se debe a que utilizamos la interfaz como referencia al bean pero existen 2 implementaciones, como vemos se hace inyección por tipo así que spring no tiene forma de saber que bean se inyectará en el atributo userService;

Para resolver el problema anterior debemos modificar la clase UserController.java como se muestra a continuación:


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;

/**
 * @author raidentrance
 *
 */
@Controller
public class UserController {
	
	@Autowired
	@Qualifier("userServiceDatabaseImpl")
	private  UserService userService;
	
	public boolean authenticate(String username, String password) {
		return userService.authenticate(username, password);
	}
}

Como vemos la anotación @Qualifier nos permite especificar el nombre del bean que se va a inyectar en el atributo.

Para estar al pendiente sobre nuestro contenido nuevo síguenos en nuestras redes sociales https://www.facebook.com/devs4j/ y https://twitter.com/devs4j.

Autor: Alejandro Agapito Bautista
Twitter: @raidentrance
Contacto:raidentrance@gmail.com

Spring framework 5 : Dependency Injection utilizando Spring


Una vez que entendimos como funciona dependency injection e inversion of control el siguiente paso es aprender a utilizarlo con Spring framework.

Crear un Service de ejemplo

El primer paso será crear un service de ejemplo, a continuación se muestra la interfaz y su implementación:

MathService.java

/**
 * 
 * @author raidentrance
 *
 */
public interface MathService {
		
	/**
	 * Receives a set of numbers and return the sum
	 * @param values
	 * @return
	 */
	double sum(double... values);

}

MathServiceImpl.java


import org.springframework.stereotype.Service;

/**
 * @author raidentrance
 *
 */
@Service
public class MathServiceImpl implements MathService {

	@Override
	public double sum(double... values) {
		double sum = 0.0;
		for (double value : values) {
			sum += value;
		}
		return sum;
	}
}

Como vemos la clase MathServiceImpl esta marcada con la anotación @Service, esta nos permitirá indicarle a spring que debe crear una instancia de esta y mantenerla dentro de su contexto.

Accediendo al objeto creado

Una vez que creamos nuestras clases MathService y MathServiceImpl el siguiente paso será utilizarlas en nuestro código, para esto haremos lo siguiente dentro de nuestra clase de aplicación:


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

import com.devs4j.service.MathService;
import com.devs4j.service.MathServiceImpl;

@SpringBootApplication
public class Devs4jSpringCoreApplication {

	public static void main(String[] args) {
		ConfigurableApplicationContext applicationContext = SpringApplication.run(Devs4jSpringCoreApplication.class,
				args);
		/**
		 * Get bean by name
		 */
		MathService bean = (MathService) applicationContext.getBean("mathServiceImpl");
		System.out.println(bean.sum(1.1, 2.3, 4.4));

		/**
		 * Get bean by type
		 */
		MathService bean2 = applicationContext.getBean(MathServiceImpl.class);
		System.out.println(bean2.sum(1, 2.3, 4));

		/**
		 * Get bean by name and type
		 */
		MathService bean3 = applicationContext.getBean("mathServiceImpl", MathServiceImpl.class);
		System.out.println(bean3.sum(1, 2.3, 4));
	}

}

Como podemos ver al iniciar la aplicación Spring framework devolverá un objeto de tipo ConfigurableApplicationContext el cual nos permitirá acceder a los beans que existen dentro del contexto de Spring, para hacerlo podremos alguno de los siguientes métodos:

  • getBean(String name) : Devuelve el objeto que tenga el nombre que se pasa como parámetro, por default el nombre del bean será el mismo al de la clase pero iniciando con minúsculas, si se desea cambiar se puede poner el nuevo nombre dentro de la anotación @Service(“nuevoNombreDelBean”).
  • getBean(Class<T> requiredType) : Devuelve un objeto del tipo que se esta solicitando.
  • getBean(String name, Class<T> requiredType) :Devuelve un objeto del tipo que se esta solicitando con el nombre que se está solicitando.

Algunas de las siguientes excepciones se pueden generar al utilizar los métodos anteriores:

  • NoUniqueBeanDefinitionException : En caso de que existan más de un bean del mismo tipo.
  • NoSuchBeanDefinitionException : En caso de que no se encuentre el bean que se está solicitando.
  • BeansException : En caso de que no se pueda crear el bean solicitado.
  • BeanNotOfRequiredTypeException : En caso de que el bean con el nombre solicitado no sea del tipo especificado.

Inyectando beans en otros beans

Una vez que ya sabemos como agregar un bean al contexto de spring y como obtenerlo, el siguiente paso es como hacer dependencias entre ellos, existen 3 formas de hacerlo, veamos una por una inyectando el servicio MathService que creamos previamente en la siguiente interfaz.

/**
 * 
 * @author raidentrance
 *
 */
public interface ComplexCalculatorService {

	/**
	 * Calculates the avergae based on a set of double values
	 * 
	 * @param values
	 * @return
	 */
	double average(double... values);

}

Inyección por constructor

La primera forma que veremos será inyección por constructor:


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author raidentrance
 *
 */
@Service
public class ComplexCalculatorServiceImpl implements ComplexCalculatorService {

	private MathService mathService;

	@Autowired
	public ComplexCalculatorServiceImpl(MathService mathService) {
		this.mathService = mathService;
	}

	@Override
	public double average(double... values) {
		double result = mathService.sum(values);
		return result / values.length;
	}
}

De acuerdo a lo anterior podemos notar que:

  • La clase en la que inyectaremos el service se debe encontrar en el contexto de spring, por esto ComplexCalculatorServiceImpl tiene la anotación @Service
  • La inyección de dependencias se hace a través del constructor, es por esto que le colocamos la anotación @Autowired en el

Inyección por setter

La siguiente forma de hacerlo será inyección por setter:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author raidentrance
 *
 */
@Service
public class ComplexCalculatorServiceImpl implements ComplexCalculatorService {

	private MathService mathService;

	@Autowired
	public void setMathService(MathService mathService) {
		this.mathService = mathService;
	}

	@Override
	public double average(double... values) {
		double result = mathService.sum(values);
		return result / values.length;
	}
}

A diferencia de la inyección por constructor en la inyección por setter la anotación @Autowired se colocará el el método setter.

Inyección por atributo

La siguiente forma de inyectar un atributo es a través de inyección por atributos:


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author raidentrance
 *
 */
@Service
public class ComplexCalculatorServiceImpl implements ComplexCalculatorService {

	@Autowired
	private MathService mathService;

	@Override
	public double average(double... values) {
		double result = mathService.sum(values);
		return result / values.length;
	}
}

Como podemos ver haciendo inyección por atributo la clase luce más simple y limpia, el problema de utilizar este método de inyección es que en el se utiliza reflection dado que el atributo es privado y no se puede acceder desde fuera de la clase.

Para estar al pendiente sobre nuestro contenido nuevo síguenos en nuestras redes sociales https://www.facebook.com/devs4j/ y https://twitter.com/devs4j

Autor: Alejandro Agapito Bautista
Twitter: @raidentrance
Contacto:raidentrance@gmail.com

Spring framework 5 : Conceptos básicos sobre DI (Dependency Injection)


En el post anterior se explicó como crear un proyecto de Spring framework 5 desde cero https://devs4j.com/2019/01/28/spring-framework-5-creando-un-proyecto-de-spring, ahora toca el turno de hablar sobre inyección de dependencias en Spring framework 5.

Introducción

La definición más simple de Dependency Injection es cuando una un objeto necesita una dependencia y esta es inyectada por otro objeto, la clase que necesita la dependencia no es responsable sobre la creación del objeto.

Veamos el siguiente ejemplo:

Las clases UserDao y RoleDao necesitan un objeto de tipo Datasource, si no se utilizara inyección de dependencias, ambas clases deberían crear su propia instancia del objeto Datasource y si en el futuro es necesario actualizar la contraseña de la base de datos o incluso el motor de base de datos ese cambio se debería hacer en ambos Daos, lo cual reduce la mantenibilidad de la aplicación.

Haciendo uso de Dependency Injection un componente puede crear el objeto de tipo Datasource solo una vez e inyectarlo en todos los componentes que lo necesiten, esto nos ayuda a que los objetos de tipo UserDao y RoleDao no tengan la necesidad de crear los objetos a la base de datos, crear conexiones o cerrarlas.

Tipos de dependency injection

Los siguientes son los tipos de inyección de dependencias en Spring:

  • Por constructor : Las dependencias de la clase se inyectarán a través del constructor
  • Por métodos setters : Las dependencias de la clase se inyectarán a través de métodos setter
  • Por atributos de la clase : Las dependencias de la clase se inyectarán haciendo uso del api de reflection, esto debido a que un atributo de una clase puede ser privado y esto hace que no se pueda acceder desde afuera.

Se puede utilizar inyección de dependencias haciendo uso de interfaces o de clases concretas, es preferible hacerlo a través de interfaces porque esto permite:

  • Decidir la implementación que se inyectará en tiempo de ejecución
  • Seguir los principios de diseño SOLID
  • Haces el código más fácil de probar

En el ejemplo anterior hablamos sobre las clases UserDao y RoleDao utilizando una referencia de tipo Datasource, la cual es una interfaz, esto me permite que no importe el tipo de datasource que yo utilice la clase UserDao y RoleDao funcionarán correctamente.

Inversion of control

Inversion of control es una técnica que permite inyectar dependencias en tiempo de ejecución, esto significa que las dependencias no serán inyectadas de forma predeterminada todo el tiempo sino que pueden variar dependiendo del contexto de ejecución.

Algunas veces las personas confunden Inversion of control con Dependency Injection, la diferencia es que dependency injection se refiere a la composición y estructura de las clases e Inversion of control se refiere más al ambiente de ejecución del código.

En este post hablamos sobre la teoría de dependency injection, en el siguiente veremos como implementarlo utilizando Spring framework 5. Para estar al pendiente sobre nuestro contenido nuevo síguenos en nuestras redes sociales  https://www.facebook.com/devs4j/ y https://twitter.com/devs4j.

Autor: Alejandro Agapito Bautista
Twitter: @raidentrance
Contacto:raidentrance@gmail.com

Spring framework 5 : Creando un proyecto de Spring


Este es el primer post de la serie Spring framework 5 y el primer paso será preparar nuestro ambiente de desarrollo.

Requerimientos

Lo primero que tendremos que asegurarnos de tener instalado en nuestro equipo lo siguiente:

Creación de un proyecto de Spring

Una vez que tenemos todo instalado utilizaremos STS para trabajar y crearemos en el nuestro primer proyecto de Spring siguiendo los siguientes pasos:

Paso 1 : Ir al menú File > New ->Other… como se muestra en la siguiente imagen:

Esta sección nos permitirá crear clases, interfaces, proyectos, etc.

Paso 2 : Seleccionar Spring boot > Spring starter project y dar click en Next como se ve en la siguiente imagen:

Seleccionamos el Spring Starter Project ya que nos permitirá configurar nuestro proyecto de spring con las herramientas que necesitemos.

Paso 3 : Especificar los siguientes valores del proyecto:

  • Name : devs4j-spring-core
  • Group : com.devs4j
  • Artifact : devs4j-spring-core

Y dar click en Next como se muestra en la imagen:

En esta sección especificaremos los detalles del proyecto como su nombre, descripción, la empresa a la que pertenece y la versión que le corresponde.

Paso 4 : Seleccionar las dependencias a utilizar, en esta sección no modificaremos nada y solo daremos click en Finish como se muestra en la imagen:

Paso 5 : El último paso será analizar el proyecto generado:

  • pom.xml : En nuestro archivo pom.xml podremos ver lo siguiente:
    • Nuestro proyecto hereda de spring-boot-starter-parent, gracias a esto no debemos de incluir las versiones de las dependencias que este incluya.
    • Se incluyeron las dependencias spring-boot-starter y spring-boot-starter-test las cuales incluyen el contexto de spring, aop, auto configuration, log4j, etc.
    • El plugin de spring boot spring-boot-maven-plugin que se utilizará para empaquetar nuestra aplicación, ejecutar tests de integración, generar información utilizada por actuator, entre otras cosas.
  • application.properties : Este archivo se utiliza para configurar nuestra aplicación (bases de datos, contextos de ejecución, etc).
  • Devs4jSpringCoreApplication.java : Clase principal de nuestra aplicación, su nombre dependerá del nombre que asignamos al crear nuestro proyecto. Utilizaremos esta clase para ejecutar nuestra aplicación, en este caso si la ejecutamos solo iniciará el contexto de spring y no hará nada.
  • Devs4jSpringCoreApplicationTests.java : Default test que validará que el contexto de spring se inicie correctamente.

Con esto tendremos nuestro entorno de desarrollo listo para empezar a desarrollar aplicaciones utilizando Spring framework 5, para estar al pendiente sobre nuestro contenido nuevo síguenos en nuestras redes sociales  https://www.facebook.com/devs4j/ y https://twitter.com/devs4j.

Autor: Alejandro Agapito Bautista
Twitter: @raidentrance
Contacto:raidentrance@gmail.com