Spring AppContext Beans (Xml y Anotaciones)
Prototipo básico de Spring por AppContext beans Core por xml
https://github.com/jalbertomr/jalbertomr-springAppContextBeans/commit/167618cb7557c6970c3e86127ebe095e73ff1937
Se modifica la configuración de xml a Anotaciones.
Se crea una clase con nombre AppConfig, que puede tener otro nombre ya que se referencia en la class main por
ApplicationContext appContext = new AnnotationConfigApplicationContext(AppConfig.class);
Se anota la Clase AppConfig con @Configuration
@Configuration
public class AppConfig {
@Bean
public ClaseParaBean cpb() {
return new ClaseParaBean();
}
@Bean
public Tierra tierra() {
return new Tierra();
}
@Bean(name = "beanMarte")
public Marte marte() {
return new Marte();
}
}
En la Clase Main
public static void main(String[] args) {
System.out.println("Iniciado...");
/* Metodo Beans */
ApplicationContext appContext =
new AnnotationConfigApplicationContext(AppConfig.class);
//ClaseParaBean cpb = (ClaseParaBean) appContext.getBean("claseBean");
ClaseParaBean cpb = (ClaseParaBean) appContext.getBean(ClaseParaBean.class);
System.out.println("ClaseParaBean.getPropiedadDeClaseMensaje:" + cpb.getPropiedadDeClaseMensaje());
Tierra tierra = (Tierra) appContext.getBean(Tierra.class);
System.out.println("Tierra color:" + tierra.getColor() );
System.out.println("Tierra diametro:" + tierra.getDiametro().toString());
Marte marte = (Marte) appContext.getBean("beanMarte");
System.out.println("Marte color:" + marte.getColor());
System.out.println("Marte diametro:" + marte.getDiametro().toString());
((ConfigurableApplicationContext)appContext).close();
}
Se modifica la AppConfig por anotaciones para tener otra AppConfig2, y se modifica la clase main en la parte de AnnotationConfigApplicationContext(..)
AnnotationConfigApplicationContext appContext = new AnnotationConfigApplicationContext();
appContext.register(AppConfig.class);
appContext.register(AppConfig2.class);
appContext.refresh();
La clase Tierra inicializa sus valores con la anotacion @Value en sus propiedades
public class Tierra {
@Value("AZUL")
private String Color;
@Value("12742")
private BigInteger diametro;
public String getColor() { return Color; }
public void setColor(String color) { Color = color; }
public BigInteger getDiametro() { return diametro; }
public void setDiametro(BigInteger diametro) { this.diametro = diametro; }
}
https://github.com/jalbertomr/jalbertomr-springAppContextBeans/commit/3202f72a3e757b986ad19fa953e0819056095bc0
Inyección por Constructor
Creamos una clase Persona, y la declaramos en el beans.xml
Clase Persona
public class Persona {
private int id;
private String nombre;
private String telefono;
public Persona(int id, String nombre, String telefono) {
this.id = id;
this.nombre = nombre;
this.telefono = telefono;
}
public Persona(int id) {
this.id = id;
}
public Persona(String telefono) {
this.telefono = telefono;
}
En bean.xml declaramos el bean de Persona y las propiedades las inicializamos con constructor
beans.xml
...
<bean id="persona" class="com.bext.beans.Persona">
<constructor-arg value="1"></constructor-arg>
<constructor-arg value="Alberto"></constructor-arg>
<constructor-arg value="4325235244"></constructor-arg>
</bean>
...
Al ejecutar la app tenemos
App.java
...
Persona per = (Persona) appContext.getBean("persona");
System.out.println(per.getId() + " " + per.getNombre() +" "+per.getTelefono());
...
Iniciado...
1 Alberto 4325235244
Si solo inicializamos en el constructor con value="1" y ejecutamos la App tenemos
<bean id="persona" class="com.bext.beans.Persona">
<constructor-arg value="1"></constructor-arg>
</bean>
Iniciado...
0 null 1
Observamos que con un solo valor en este caso "1" lo toma como String, o sea toma el constructor con un solo parametro de tipo String, pero este corresponde al Telefono. para que tome el int, hay que especificar el type="int"
<bean id="persona" class="com.bext.beans.Persona">
<constructor-arg type="int" value="1"></constructor-arg>
</bean>
Iniciado...
1 null null
Si especificamos el type="String" tomará el constructor con parámetro type String que corresponde al Telefono.
<bean id="persona" class="com.bext.beans.Persona">
<constructor-arg type="String" value="1234567"></constructor-arg>
</bean>
Iniciado...
0 null 1234567
Podemos indicar la posición del parametro del constructor a inicializar
...
<bean id="persona" class="com.bext.beans.Persona">
<constructor-arg index="2" value="1234567"></constructor-arg>
<constructor-arg index="0" value="1"></constructor-arg>
<constructor-arg index="1" value="Alberto"></constructor-arg>
</bean>
...
Iniciado...
1 Alberto 1234567
Inyección de Objectos
A la Clase Persona le agregamos la Clase Pais.Pais.java
public class Pais {
private String nombre;
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
}
Persona.java
public class Persona {
private int id;
private String nombre;
private String telefono;
private Pais pais;
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getNombre() { return nombre;}
public void setNombre(String nombre) { this.nombre = nombre;}
public String getTelefono() { return telefono; }
public void setTelefono(String telefono) { this.telefono = telefono; }
public Pais getPais() { return pais;}
public void setPais(Pais pais) {this.pais = pais;}
}
App.java
public class App {
public static void main(String[] args) {
System.out.println("Iniciado...");
/* Metodo Beans */
ApplicationContext appContext = new ClassPathXmlApplicationContext("com/bext/xml/beans.xml");
//AnnotationConfigApplicationContext appContext = new AnnotationConfigApplicationContext();
//appContext.register(AppConfig.class);
//appContext.register(AppConfig2.class);
//appContext.refresh();
Persona per = (Persona) appContext.getBean("persona");
System.out.println(per.getId() + " " + per.getNombre() +" "+per.getTelefono() + " "+ per.getPais().getNombre());
((ConfigurableApplicationContext)appContext).close();
}
}
beans.xml
...
<bean id="persona" class="com.bext.beans.Persona">
<property name="pais" ref="pais"></property>
<property name="id" value="1"></property>
<property name="nombre" value="Alberto"></property>
<property name="telefono" value="1234567"></property>
</bean>
<bean id="pais" class="com.bext.beans.Pais">
<property name="nombre" value="Mexico"></property>
</bean>
...
Ejecución
Iniciado...
1 Alberto 1234567 Mexico
Inyección de sub-Objeto
Ahora agregamos otra clase a la de Pais, será Ciudad.
Ciudad.java
public class Ciudad {
private String nombre;
public String getNombre() { return nombre;}
public void setNombre(String nombre) {this.nombre = nombre;}
}
Pais.java
public class Pais {
private String nombre;
private Ciudad ciudad;
public String getNombre() { return nombre; }
public void setNombre(String nombre) { this.nombre = nombre; }
public Ciudad getCiudad() { return ciudad; }
public void setCiudad(Ciudad ciudad) { this.ciudad = ciudad;}
}
beans.xml
...
<bean id="persona" class="com.bext.beans.Persona">
<property name="pais" ref="pais"></property>
<property name="id" value="1"></property>
<property name="nombre" value="Alberto"></property>
<property name="telefono" value="1234567"></property>
</bean>
<bean id="pais" class="com.bext.beans.Pais">
<property name="nombre" value="Mexico"></property>
<property name="ciudad" ref="ciudad"></property>
</bean>
<bean id="ciudad" class="com.bext.beans.Ciudad">
<property name="nombre" value="CDMX"></property>
</bean>
...
App.java
...
Persona per = (Persona) appContext.getBean("persona");
System.out.println(per.getId() + " " + per.getNombre() +" "+per.getTelefono() + " "+ per.getPais().getNombre() + " "+per.getPais().getCiudad().getNombre());...
Ejecución
Iniciado...
1 Alberto 1234567 Mexico CDMX
https://github.com/jalbertomr/jalbertomr-springAppContextBeans/commit/aa26774b29d7c021faf11faa7fdc67eaa47813de
Anidando Beans
Integramos Ciudad dentro de Pais
<bean id="persona" class="com.bext.beans.Persona">
<property name="pais" ref="pais"></property>
<property name="id" value="1"></property>
<property name="nombre" value="Alberto"></property>
<property name="telefono" value="1234567"></property>
</bean>
<bean id="pais" class="com.bext.beans.Pais">
<property name="nombre" value="Mexico"></property>
<property name="ciudad">
<bean id="ciudad" class="com.bext.beans.Ciudad">
<property name="nombre" value="CDMX"></property>
</bean>
</property>
</bean>
Ahora Integramos Ciudad dentro de Persona
<bean id="persona" class="com.bext.beans.Persona">
<property name="pais">
<bean id="pais" class="com.bext.beans.Pais">
<property name="nombre" value="Mexico"></property>
<property name="ciudad">
<bean id="ciudad" class="com.bext.beans.Ciudad">
<property name="nombre" value="CDMX"></property>
</bean>
</property>
</bean>
</property>
<property name="id" value="1"></property>
<property name="nombre" value="Alberto"></property>
<property name="telefono" value="1234567"></property>
</bean>
https://github.com/jalbertomr/jalbertomr-springAppContextBeans/commit/2817c32acb881ab56797c8cae565cee9e5317970
Referenciando Beans (Alias)
Creamos un alias en beans.xml para Persona
<alias name="persona" alias="personaAlias"></alias>
Y se llama este alias desde App.java
Persona per = (Persona) appContext.getBean("personaAlias");
Tambien podemos poner el nombre de alias en la definición del bean de Persona con nombre="personaAlias2"
<bean id="persona" class="com.bext.beans.Persona" name="personaAlias2">
<property name="pais" ref="pais"></property>
<property name="id" value="1"></property>
<property name="nombre" value="Alberto"></property>
<property name="telefono" value="1234567"></property>
</bean>
https://github.com/jalbertomr/jalbertomr-springAppContextBeans/commit/3dfbd46fb0850f4ba00a228dd72ac700682ab9ba
Colecciones (Lista) Beans
Vamos a definir valores para las ciudades del pais por medio de inicialización por xml.beans.xml
...
<bean id="persona" class="com.bext.beans.Persona" name="personaAlias2">
<property name="pais" ref="pais"></property>
<property name="id" value="1"></property>
<property name="nombre" value="Alberto"></property>
<property name="telefono" value="1234567"></property>
</bean>
<bean id="pais" class="com.bext.beans.Pais">
<property name="nombre" value="Mexico"></property>
<property name="ciudades">
<list>
<ref bean="ciudad1"></ref>
<ref bean="ciudad2"></ref>
<ref bean="ciudad3"></ref>
</list>
</property>
</bean>
<bean id="ciudad1" class="com.bext.beans.Ciudad">
<property name="nombre" value="CDMX"></property>
</bean>
<bean id="ciudad2" class="com.bext.beans.Ciudad">
<property name="nombre" value="Tepatitlan"></property>
</bean>
<bean id="ciudad3" class="com.bext.beans.Ciudad">
<property name="nombre" value="Guadalajara"></property>
</bean>
...
La App.java la modificamos para que podamos desplegar la lista
...
Persona per = (Persona) appContext.getBean("personaAlias2");
System.out.println(per.getId() + " " + per.getNombre() +" "+per.getTelefono() + " "+ per.getPais().getNombre());
for (Ciudad ciudad: per.getPais().getCiudades()) {
System.out.println(ciudad.getNombre());
}
...
Ejecución
Iniciado...
1 Alberto 1234567 Mexico
CDMX
Tepatitlan
Guadalajara
https://github.com/jalbertomr/jalbertomr-springAppContextBeans/commit/ff559934528cd433081c8d3caf9347f897e9364b
AutoWire
Modificamos a Pais para que no tenga la propiedad Ciudad, se traslada esta propiedad a Persona.En beans.xml borramos las propiedades que asignaban a Pais y Ciudad, estos valores se tomaran con autowire la cual las asociará por nombre.
beans.xml
...
<bean id="persona" class="com.bext.beans.Persona" autowire="byName">
<property name="id" value="1"></property>
<property name="nombre" value="Alberto"></property>
<property name="telefono" value="1234567"></property>
</bean>
<bean id="pais" class="com.bext.beans.Pais">
<property name="nombre" value="Mexico"></property>
</bean>
<bean id="ciudad" class="com.bext.beans.Ciudad">
<property name="nombre" value="CDMX"></property>
</bean>
...
Persona.java
public class Persona {
private int id;
private String nombre;
private String telefono;
private Pais pais;
private Ciudad ciudad;
...
Ejecutando
Iniciado...
1 Alberto 1234567 Mexico CDMX
El autowire puede hacerse tambien por type "byType", así asignará las propiedades de personas comparadas por tipo, pero si hay dos o más tipos no sabrá a que bean asignar la propiedad. Tambien esta autowire por constructor.
Scope (Singleton, Prototype)
Prototype genera instancias diferentes por bean...
<bean id="persona" class="com.bext.beans.Persona" autowire="byName" scope="prototype">
<property name="id" value="1"></property>
<property name="nombre" value="Alberto"></property>
<property name="telefono" value="1234567"></property>
</bean>
...
Ejecución
Iniciado...
1 Alberto 1234567 Mexico CDMX
com.bext.beans.Persona@6fc6f14e
com.bext.beans.Persona@56235b8e
Singleton genera una sola instancia por cada bean que se cree.
...<bean id="persona" class="com.bext.beans.Persona" autowire="byName" scope="singleton">
<property name="id" value="1"></property>
<property name="nombre" value="Alberto"></property>
<property name="telefono" value="1234567"></property>
</bean>
...
Ejecución
Iniciado...
1 Alberto 1234567 Mexico CDMX
com.bext.beans.Persona@6fc6f14e
com.bext.beans.Persona@6fc6f14e
https://github.com/jalbertomr/jalbertomr-springAppContextBeans/commit/21d6eb30019cf7785188e7af715203808d58b6c0
eot
No hay comentarios:
Publicar un comentario