En el siguiente post voy a explicar acerca Configuraciones
en Java usando Spring. La idea principal de usar configuraciones en Java es
para definir métodos que inicializan objetos para que el contenido IoC de
Spring lo maneje.
Vamos a crear un simple proyecto usando Intellij que nos
ayude a entender este concepto. Vamos a crear un simple objeto POJO (Plain Old
Java Object).
Esta es la organización del proyecto:
Note los archivos que empiezan con I. Voy a usar esta
nomenclatura (C#...Sin ofender) para representar interfaces. Los archivos sin I
son implementaciones de dichas interfaces.
Aquí esta el contendido de cada archivo. Algunos valores
están directamente guardados en el código, pero es para simplificar y también
para dar paso al tema de este post.
Entidad Película:
public class Pelicula
{
private Integer Id;
private String nombre;
private String pais;
private String genero;
public Pelicula() {
}
public Integer getId() {
return Id;
}
public void setId(Integer id) {
Id = id;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getPais() {
return pais;
}
public void setPais(String pais) {
this.pais = pais;
}
public String getGenero() {
return genero;
}
public void setGenero(String genero) {
this.genero = genero;
}
}
private Integer Id;
private String nombre;
private String pais;
private String genero;
public Pelicula() {
}
public Integer getId() {
return Id;
}
public void setId(Integer id) {
Id = id;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getPais() {
return pais;
}
public void setPais(String pais) {
this.pais = pais;
}
public String getGenero() {
return genero;
}
public void setGenero(String genero) {
this.genero = genero;
}
}
Interfaz Repositorio Película:
public interface IRepositorioPelicula { List<Pelicula> todasLasPeliculas(); }
Implementación de Repositorio Película:
public class RepositorioPelicula implements IRepositorioPelicula { @Override public List<Pelicula> todasLasPeliculas() { List<Pelicula> peliculas = new ArrayList<>(); Pelicula pelicula = new Pelicula(); pelicula.setId(1); pelicula.setNombre("Captain Marvel"); pelicula.setPais("Estados Unidos"); pelicula.setGenero("Accion"); peliculas.add(pelicula); return peliculas; } }
Interfaz Servicio Película:
public interface IServicioPelicula { List<Pelicula> todasLasPeliculas(); }
Servicio Película:
public class ServicioPelicula implements IServicioPelicula { private IRepositorioPelicula repositorio = new RepositorioPelicula(); @Override public List<Pelicula> todasLasPeliculas() { return repositorio.todasLasPeliculas(); } }
Aplicación:
public class Aplicacion { public class Aplicacion { public static void main(String[] args) { IServicioPelicula servicio = new ServicioPelicula(); System.out.println(servicio.todasLasPeliculas().get(0).getId()); System.out.println(servicio.todasLasPeliculas().get(0).getNombre()); System.out.println(servicio.todasLasPeliculas().get(0).getGenero()); System.out.println(servicio.todasLasPeliculas().get(0).getPais()); } }
¡Perfecto! Tenemos una aplicación que usa al servicio
ServicioPelicula, y que luego usa en ese servicio el repositorio
RepositorioPelicula. El siguiente paso es hacer este código mas limpio
inyectando ciertos valores usando Configuración en Java. Para eso vamos a usar el archivo AplConfiguracion.
Para crear una clase que soporte configuraciones en Java
necesitamos las siguientes anotaciones:
@Configuration
@Bean
@Configuration. Esta anotación se coloca solamente en
clases. Se usa para declarar beans que van a poder ser procesados por el Contenedor
IoC de Spring.
@Bean. Esta anotación se usa en métodos para que retornen
instancias de un Bean.
Vamos a crear un simple ejemplo usando nuestro servicio película.
@Configuration
public class AplConfiguracion {
@Bean
public IServicioPelicula servicioPelicula() {
return new ServicioPelicula();
}
}
public class AplConfiguracion {
@Bean
public IServicioPelicula servicioPelicula() {
return new ServicioPelicula();
}
}
Como mencione anteriormente la anotación @Configuracion
esta encima de la declaración de la clase. En dicha clase tenemos el bean
servicioPelicula. De esta manera podemos usar este bean en nuestra aplicación inyectadola.
Para eso
tenemos diferentes formas de inyectar a bean: setters y constructors.
En este ejemplo vamos a usar inyección usando constructor.
Tenemos que modificar nuestro servicio película para que acepte el repositorio película
en su constructor.
public class ServicioPelicula
implements IServicioPelicula
{
private IRepositorioPelicula repositorio;
public ServicioPelicula(IRepositorioPelicula repositorio) {
this.repositorio = repositorio;
}
@Override
public List<Pelicula> todasLasPeliculas() {
return repositorio.todasLasPeliculas();
}
}
private IRepositorioPelicula repositorio;
public ServicioPelicula(IRepositorioPelicula repositorio) {
this.repositorio = repositorio;
}
@Override
public List<Pelicula> todasLasPeliculas() {
return repositorio.todasLasPeliculas();
}
}
También debemos cambiar el bean que retorna servicio película
y además añadir el bean para el repositorio película. Nuestra configuración AplConfiguracion
queda de la siguiente manera:
@Configuration
public class AplConfiguracion {
@Bean
public IServicioPelicula servicioPelicula() {
return new ServicioPelicula(repositorioPelicula());
}
@Bean
public IRepositorioPelicula repositorioPelicula() {
return new RepositorioPelicula();
}
}
public class AplConfiguracion {
@Bean
public IServicioPelicula servicioPelicula() {
return new ServicioPelicula(repositorioPelicula());
}
@Bean
public IRepositorioPelicula repositorioPelicula() {
return new RepositorioPelicula();
}
}
Los métodos que están marcados con la anotación @Bean ahora
esta disponibles en el Spring Context. Ahora para que esos beans sean encontrados
por nuestra aplicación anadimos la siguiente línea:
public class Aplicacion
{
public static void main(String[] args) {
ApplicationContext applicationContext =
new AnnotationConfigApplicationContext(AplConfiguracion.class);
IServicioPelicula servicio =
applicationContext.getBean("servicioPelicula",ServicioPelicula.class);
System.out.println(servicio.todasLasPeliculas().get(0).getId());
System.out.println(servicio.todasLasPeliculas().get(0).getNombre());
System.out.println(servicio.todasLasPeliculas().get(0).getGenero());
System.out.println(servicio.todasLasPeliculas().get(0).getPais());
}
}
public static void main(String[] args) {
ApplicationContext applicationContext =
new AnnotationConfigApplicationContext(AplConfiguracion.class);
IServicioPelicula servicio =
applicationContext.getBean("servicioPelicula",ServicioPelicula.class);
System.out.println(servicio.todasLasPeliculas().get(0).getId());
System.out.println(servicio.todasLasPeliculas().get(0).getNombre());
System.out.println(servicio.todasLasPeliculas().get(0).getGenero());
System.out.println(servicio.todasLasPeliculas().get(0).getPais());
}
}
Ejecutamos la aplicación y obtenemos:
1
Captain Marvel
Accion
Estados Unidos
Lo mismo podemos hacer con la anotación @Autowired. Para
eso necesitamos modificar menormente nuestra aplicación.
Cambiemos nuestra configuracion aplicación a lo
siguiente:
@Configuration
@ComponentScan({"com.example"})
public class AplConfiguracion {
}
@ComponentScan({"com.example"})
public class AplConfiguracion {
}
@ComponentScan nos va a ayudar a buscar beans que existen
en nuestra aplicación. Tenemos dos beans, pero Spring no sabe cuales son. Para
eso vamos añadir las siguientes anotaciones en nuestro ServicioPelicula y
RepositorioPelicula: @Service y @Repository. Con estas anotaciones Spring
entiend que esas dos clases son beans components. Ahora las clases quedan de la
siguiente manera:
@Service
public class ServicioPelicula implements IServicioPelicula {
private IRepositorioPelicula repositorio;
@Autowired
public ServicioPelicula(IRepositorioPelicula repositorio) {
this.repositorio = repositorio;
}
@Override
public List<Pelicula> todasLasPeliculas() {
return repositorio.todasLasPeliculas();
}
}
public class ServicioPelicula implements IServicioPelicula {
private IRepositorioPelicula repositorio;
@Autowired
public ServicioPelicula(IRepositorioPelicula repositorio) {
this.repositorio = repositorio;
}
@Override
public List<Pelicula> todasLasPeliculas() {
return repositorio.todasLasPeliculas();
}
}
@Repository
public class RepositorioPelicula implements IRepositorioPelicula {
@Override
public List<Pelicula> todasLasPeliculas() {
List<Pelicula> peliculas = new ArrayList<>();
Pelicula pelicula = new Pelicula();
pelicula.setId(1);
pelicula.setNombre("Captain Marvel");
pelicula.setPais("Estados Unidos");
pelicula.setGenero("Accion");
peliculas.add(pelicula);
return peliculas;
}
}
public class RepositorioPelicula implements IRepositorioPelicula {
@Override
public List<Pelicula> todasLasPeliculas() {
List<Pelicula> peliculas = new ArrayList<>();
Pelicula pelicula = new Pelicula();
pelicula.setId(1);
pelicula.setNombre("Captain Marvel");
pelicula.setPais("Estados Unidos");
pelicula.setGenero("Accion");
peliculas.add(pelicula);
return peliculas;
}
}
La anotación @Autowired puede ser omitido si el bean
define un constructor. Ejecutamos el archivo aplicación y tendremos el resultado
anterior.
Comments
Post a Comment