Escolar Documentos
Profissional Documentos
Cultura Documentos
com.apress.prospring5.ch3.annotation paquete;
org.springframework.context.annotation.ComponentScan importación;
org.springframework.context.annotation.Configuration importación;
El código para inicializar un ambiente de primavera usando AnnotationConfigApplicationContext trabajará con esta clase también, sin
cambios adicionales.
En las aplicaciones de producción de la vida real, puede haber código heredado, desarrollado con las versiones anteriores de la primavera, o
requisitos podrían ser de tal naturaleza que requiere clases XML y configuración. Afortunadamente, XML y la configuración de Java se pueden mezclar
en más de una forma. Por ejemplo, una clase de configuración puede importar las definiciones de frijol de un archivo XML (o más) usando @ ImportResource,
y el mismo bootstrapping usando AnnotationConfigApplicationContext funcionará en este caso también.
com.apress.prospring5.ch3.mixed paquete;
org.springframework.context.annotation.ComponentScan importación;
org.springframework.context.annotation.Configuration importación;
org.springframework.context.annotation.ImportResource importación;
Por lo tanto, la primavera le permite ser muy creativo en la definición de los granos; usted aprenderá más sobre esto en el capítulo 4 , Que se centra
únicamente en la configuración de la aplicación de primavera.
Para configurar la inyección colocador mediante el uso de la configuración de XML, es necesario especificar < propiedad> links debajo de la
<Bean> etiqueta para cada < propiedad> en la que desea inyectar una dependencia. Por ejemplo, para asignar el proveedor de frijol mensaje al messageProvider
propiedad de la messageRenderer frijol, sólo tiene que cambiar el < bean> etiqueta para el renderizador bean, como se muestra en el siguiente fragmento
de código:
<Habas ...>
<Bean id = "renderer"
class => <name = ref = "proveedor"
"com.apress.prospring5.ch2.decoupled.StandardOutMessageRenderer" "messageProvider" propiedad /> </
bean>
<Bean id = "proveedor"
class = "com.apress.prospring5.ch2.decoupled.HelloWorldMessageProvider" /> </ beans>
56
Capítulo 3 ■ La introducción de la COI y Di en primavera
A partir de este código, podemos ver que la proveedor frijol se asigna a la messageProvider propiedad. Se puede utilizar el árbitro atribuir a
asignar una referencia a una propiedad de frijol (discutido en más detalle en breve).
Si está utilizando Primavera 2.5 o posterior y tener la p espacio de nombres declarada en el archivo de configuración XML, se puede declarar la inyección
como se muestra en el siguiente fragmento de código:
<Bean id = "renderer"
class = "com.apress.prospring5.ch2.decoupled.StandardOutMessageRenderer" t:
messageProvider-ref = "proveedor" />
<Bean id = "proveedor"
class = "com.apress.prospring5.ch2.decoupled.HelloWorldMessageProvider" /> </ beans>
la p espacio de nombres no está definido en un archivo XSD y existe sólo en el núcleo de primavera; Por lo tanto, hay XSD se declara en
el schemaLocation atributo.
Con anotaciones, que es aún más simple. Sólo tiene que añadir un @ Autowired anotación con el método setter, como se muestra en el
siguiente fragmento de código:
com.apress.prospring5.ch3.annotation paquete;
...
org.springframework.beans.factory.annotation.Autowired importación;
@Service ( "renderer")
StandardOutMessageRenderer clase pública implementa MessageRenderer {
...
@ Override
@Autowired
setMessageProvider pública vacío (proveedor de MessageProvider) {
this.messageProvider = proveedor; }}
Dado que declaramos la < Contexto: componente de exploración> etiqueta en el archivo de configuración XML, durante la inicialización de la primavera
de Application Context, Primavera descubrirá los @ Autowired anotaciones y inyectar la dependencia según sea necesario.
57
Capítulo 3 ■ La introducción de la COI y Di en primavera
En lugar de @ Autowired, puedes usar @ Recursos (name = "messageProvider") para lograr el mismo resultado.
@Recurso es una de las anotaciones en el estándar JSR-250 que define un conjunto común de anotaciones Java para su uso en ambas
parámetro para más requisitos dI de grano fino. Además, Spring apoya el uso de la @ Inyectar anotación introducida como parte de JSR-299 (Contextos y
la inyección de dependencias para la plataforma Java EE). @ Inyectar es equivalente a la primavera en el comportamiento de @ Autowired anotación.
Para verificar el resultado, puede utilizar DeclareSpringComponents que se presentó anteriormente. Al igual que en el apartado anterior, se
puede intercambiar la App-contexto-xml.xml presentar ante App-contexto-annotation.xml en el código fuente proporcionado para este capítulo, y se
encuentra que ambos casos producen el mismo resultado: “Hello World!” se imprime.
En el ejemplo anterior, el MessageProvider implementación, HelloWorldMessageProvider, devuelto el mismo mensaje codificado para cada llamada de la getMessage
() método. En el archivo de configuración de la primavera, puede crear fácilmente un configurable MessageProvider que permite que el mensaje para ser
definida externamente, como se muestra en el siguiente fragmento de código:
com.apress.prospring5.ch3.xml paquete;
com.apress.prospring5.ch2.decoupled.MessageProvider importación;
@Anular
Cadena getMessage pública () {
mensaje de retorno; }}
Como se puede ver, es imposible crear una instancia de ConfigurableMessageProvider sin proporcionar un valor para el mensaje (a menos
que suministre nulo). Esto es exactamente lo que queremos, y esta clase es ideal para su uso con la inyección de constructor. El siguiente
fragmento de código muestra cómo se puede redefinir el
proveedor definición de frijol para crear una instancia de ConfigurableMessageProvider, inyectar el mensaje mediante el uso de inyección de constructor:
<Bean id = "messageProvider"
58
Capítulo 3 ■ La introducción de la COI y Di en primavera
En este código, en lugar de utilizar un < propiedad> tag, se utilizó un < constructor-arg> etiqueta. Debido a que no estamos de paso en otro
grano de este tiempo, sólo una Cuerda literal, se utiliza el valor en lugar de atribuir árbitro para especificar el valor para el argumento del
constructor. Al tener más de un argumento del constructor o de su clase tiene más de un constructor, es necesario dar a cada < constructor-arg> etiquetar
un atributo de índice para especificar el índice del argumento, comenzando en 0, en la firma constructora. Siempre es mejor utilizar el atributo de
índice cada vez que se trata de constructores que tienen varios argumentos, para evitar la confusión entre los parámetros y asegurarse de que la
primavera recoge el constructor correcto.
Además de pag espacio de nombres, a partir de la primavera 3.1, también se puede utilizar el do espacio de nombres, como se muestra aquí:
<Bean id = "proveedor"
class = "com.apress.prospring5.ch3.xml.ConfigurableMessageProvider" c: message =
"Espero que alguien reciba mi mensaje en una botella" /> </ beans>
la do espacio de nombres no está definido en un archivo XSD tampoco y sólo existe en el resorte del núcleo; Por lo tanto, hay XSD se declara en
el schemaLocation atributo.
Para utilizar una anotación para la inyección de constructor, también utilizamos el @ Autowired anotación en el método constructor del bean de
destino, que es una opción alternativa a la inyección usando setter, como se muestra en el siguiente fragmento de código:
com.apress.prospring5.ch3.annotated paquete;
com.apress.prospring5.ch2.decoupled.MessageProvider importación;
org.springframework.beans.factory.annotation.Autowired importación;
org.springframework.stereotype.Service importación;
@Proveedor de servicio")
ConfigurableMessageProvider clase pública implementa MessageProvider {
@Autowired
ConfigurableMessageProvider pública (
(( "Mensaje configurable") String mensaje @Valor) {
this.message = mensaje; }
59
Capítulo 3 ■ La introducción de la COI y Di en primavera
@Anular
Cadena getMessage pública () {
volver this.message; }}
A partir del código anterior, podemos ver que usamos otra anotación, @ Valor, para definir el valor a ser inyectado en el constructor. Esta es la
manera en la primavera inyectamos valores en un grano. Además de cadenas simples, podemos utilizar la poderosa SpEL para el valor de inyección
dinámica (más sobre esto más adelante en este capítulo).
Sin embargo, difíciles de codificar el valor en el código no es una buena idea; para cambiarlo, sería necesario volver a compilar el programa. Incluso si
decide DI-estilo de anotación, una buena práctica consiste en exteriorizar esos valores para inyección. Exteriorizar el mensaje, vamos a definir el mensaje como
un grano de primavera en el archivo de configuración de anotación, como se muestra en el siguiente fragmento de código:
<Habas ...>
<Context: componente-scan
base paquete = "com.apress.prospring5.ch3.annotated" />
Aquí definimos un grano con un ID de mensaje y el tipo de java.lang.String. Tenga en cuenta que también utilizamos la
do espacio de nombres para la inyección de constructor para establecer el valor de la cadena, y _ 0 indica el índice para el argumento del constructor. Tener
el frijol declaró, podemos quitar el @ Valor anotación de la haba de destino, como se muestra en el siguiente fragmento de código:
com.apress.prospring5.ch3.annotated paquete;
com.apress.prospring5.ch2.decoupled.MessageProvider importación;
org.springframework.beans.factory.annotation.Autowired importación;
org.springframework.stereotype.Service importación;
@Proveedor de servicio")
ConfigurableMessageProvider clase pública implementa MessageProvider {
@Autowired
ConfigurableMessageProvider pública (String mensaje) {
this.message = mensaje; }
@Anular
Cadena getMessage pública () {
volver this.message; }}
60
Capítulo 3 ■ La introducción de la COI y Di en primavera
Desde declaramos que el grano de mensaje y su ID son los mismos que el nombre del argumento especificado en el constructor,
Spring detectará la anotación e inyectar el valor en el método constructor. Ahora ejecute la prueba usando el siguiente código en contra
tanto el XML ( app-context.xml.xml) y configuraciones de anotación ( app-contexto-annotation.xml), y el mensaje configurado se mostrará
en ambos casos:
com.apress.prospring5.ch3 paquete;
com.apress.prospring5.ch2.decoupled.MessageProvider importación;
org.springframework.context.support.GenericXmlApplicationContext importación;
En algunos casos, la primavera le resulta imposible decir qué constructor queremos que se utilice para la inyección de constructor. Esto por lo general
se presenta cuando tenemos dos constructores con el mismo número de argumentos y de los tipos utilizados en los argumentos están representados de la
misma manera. Considere el siguiente código:
com.apress.prospring5.ch3.xml paquete;
org.springframework.context.support.GenericXmlApplicationContext importación;
61
Capítulo 3 ■ La introducción de la COI y Di en primavera
ConstructorConfusion cc = (ConstructorConfusion)
ctx.getBean ( "constructorConfusion");
System.out.println (cc); ctx.close}}
Esto simplemente recupera un grano de tipo ConstructorConfusion desde Application Context y escribe el valor a la consola de salida.
Ahora mira el siguiente código de configuración:
<Habas ...>
<Bean id = "proveedor"
class = "com.apress.prospring5.ch3.xml.ConfigurableMessageProvider" c: message =
"Espero que alguien reciba mi mensaje en una botella" />
<Bean id = "constructorConfusion"
class = "com.apress.prospring5.ch3.xml.ConstructorConfusion"> <constructor-arg>
</ Beans>
¿Cuál de los constructores se llama en este caso? Ejecutar el ejemplo se obtiene el resultado siguiente:
Esto demuestra que el constructor con la Cuerda argumento se llama. Este no es el efecto deseado, ya que queremos prefijo cualquier valor entero
pasado en mediante el uso de inyección de constructor con Número:, como se muestra en la
En t constructor. Para evitar esto, hay que hacer una pequeña modificación en la configuración, como se muestra en el siguiente fragmento de código:
<Habas ...>
<Bean id = "proveedor"
class = "com.apress.prospring5.ch3.xml.ConfigurableMessageProvider" c: message =
"Espero que alguien reciba mi mensaje en una botella" />
<Bean id = "constructorConfusion"
class = "com.apress.prospring5.ch3.xml.ConstructorConfusion"> <constructor-arg
tipo = "int">
<Valor> 90 </ value> </
constructor-arg> </ bean>
</ Beans>
Aviso ahora que el < constructor-arg> etiqueta tiene un atributo adicional, tipo, que especifica el tipo de argumento resorte debe
buscar. Ejecutar el ejemplo de nuevo con la configuración corregido produce la salida correcta.
62
Capítulo 3 ■ La introducción de la COI y Di en primavera
Para la inyección de la construcción de estilo de anotación, la confusión se puede evitar mediante la aplicación de la anotación directamente al método
com.apress.prospring5.ch3.annotated paquete;
org.springframework.beans.factory.annotation.Autowired importación;
org.springframework.beans.factory.annotation.Value importación;
org.springframework.context.support.GenericXmlApplicationContext importación;
org.springframework.stereotype.Service importación;
@Autowired
ConstructorConfusion pública (@Valor ( "90") int someValue) {
System.out.println ( "ConstructorConfusion (int) llama"); this.someValue =
"Número:" + Integer.toString (someValue); }
ConstructorConfusion cc = (ConstructorConfusion)
ctx.getBean ( "constructorConfusion");
System.out.println (cc); ctx.close (); }}
Mediante la aplicación de la @ Autowired anotación para el método constructor deseado, Spring utilizará ese método para instanciar el bean e
inyectar el valor como se especifica. Al igual que antes, debemos exteriorizar el valor de la configuración.
la @ Autowired anotación se puede aplicar a solamente uno de los métodos constructor. Si aplicamos la anotación a más de un
63
Capítulo 3 ■ La introducción de la COI y Di en primavera
Hay un tercer tipo de inyección de dependencias apoyado en la primavera de llamada inyección de campo. Como su nombre lo dice, la
dependencia se inyecta directamente en el campo, con ningún constructor o colocador necesario. Esto se realiza anotando el miembro de la clase
con el Autowired anotación. Esto puede parecer práctico, porque cuando la dependencia no es necesaria fuera del objeto que es parte de, alivia el
desarrollador de escribir un código que ya no se usa después de la creación inicial del grano. En el siguiente fragmento de código, el grano de
tipo Cantante tiene un campo de tipo Inspiración:
com.apress.prospring5.ch3.annotated paquete;
org.springframework.beans.factory.annotation.Autowired importación;
org.springframework.stereotype.Service importación;
@Autowired
inspirationBean inspiración privada;
El campo es privado, pero el contenedor primavera COI no le importa realmente en eso; que utiliza la reflexión para poblar la dependencia
requerida. los Inspiración código de clase se muestra aquí; es un grano simple con una
Cuerda miembro:
com.apress.prospring5.ch3.annotated paquete;
org.springframework.beans.factory.annotation.Value importación;
org.springframework.stereotype.Component importación;
@Componente
La inspiración pública (
@Value ( "Para toda mi carrera, puedo entender") lírica String) {this.lyric = lírica; }
64
Capítulo 3 ■ La introducción de la COI y Di en primavera
La siguiente configuración utiliza la exploración componente para descubrir las definiciones de frijol que serán creados por el contenedor del
resorte IoC:
<Habas ...>
<Context: componente-scan
base paquete = "com.apress.prospring5.ch3.annotated" />
</ Beans>
Encontrar un grano de tipo Inspiración, el contenedor del resorte IoC inyectará que bean en el
inspirationBean miembro de cantante frijol. Es por eso que cuando se ejecuta el ejemplo representado en el siguiente fragmento de código, “Para
toda mi carrera, puedo entender” se imprimirá en la consola.
com.apress.prospring5.ch3.annotated paquete;
org.springframework.context.support.GenericXmlApplicationContext importación;
GenericXmlApplicationContext ctx =
nuevo GenericXmlApplicationContext (); ctx.load ( "ruta
de clase: primavera / app-context.xml"); ctx.refresh ();
ctx.close (); }}
Pero también hay desventajas, y es por eso usar la inyección de campo se suele evitarse.
• Aunque es fácil de agregar dependencias de esta manera, hay que tener cuidado de no violar el principio de la responsabilidad
individual. Tener más dependencias significa más responsabilidades de una clase, que podría conducir a una dificultad de separar las
preocupaciones en el tiempo de refactorización. La situación en la que una clase se convierte en hinchada es más fácil de ver cuando
dependencias se establecen con constructores o fijadores pero está bastante bien ocultos cuando se utiliza la inyección de campo.
• inyección campo presenta una dependencia del recipiente Spring, como el @ Autowired
anotación es un componente de primavera; Por lo tanto, el grano ya no es un POJO y no puede ser instanciada
independientemente.
• inyección de campo no puede ser utilizado para los campos finales. Este tipo de campos sólo se puede inicializar mediante la inyección de
constructor.
• El campo de inyección presenta dificultades a la hora de escribir pruebas como las dependencias tienen que inyectarse manualmente.
sesenta y cinco
Capítulo 3 ■ La introducción de la COI y Di en primavera
En los tres ejemplos anteriores, que vio cómo inyectar otros componentes y valores en un grano mediante el uso tanto de la inyección de la moda y la inyección
de constructor. Primavera es compatible con una gran variedad de opciones para los parámetros de inyección, lo que le permite no sólo inyecta otros
componentes y valores simples, sino también colecciones de Java, propiedades definidas externamente, e incluso los frijoles en otra fábrica. Puede utilizar todos
estos tipos de parámetros de inyección tanto para la inyección de la inyección y constructor setter utilizando la etiqueta correspondiente en la < propiedad> y
La inyección de valores simples en sus granos es fácil. Para ello, basta con especificar el valor de la etiqueta de configuración, envuelto dentro de un < valor> etiqueta.
Por defecto, no sólo puede el < valor> leer la etiqueta Cuerda valores, pero también puede convertir estos valores a cualquier clase de contenedor primitiva o
primitivas. El siguiente fragmento de código muestra un grano simple que tiene una variedad de propiedades expuestas para inyección:
com.apress.prospring5.ch3.xml paquete;
org.springframework.context.support.GenericXmlApplicationContext importación;
66
Capítulo 3 ■ La introducción de la COI y Di en primavera
Además de las propiedades, el InjectSimple clase también define la principal() método que crea una
contexto de aplicación y a continuación, recupera una InjectSimple frijol de primavera. Los valores de las propiedades de este frijol se escriben en la
salida de la consola. La configuración contenida en App-contexto-xml.xml para este bean se representa en el siguiente fragmento:
<Habas ...>
<Bean id = "injectSimpleConfig"
class = "com.apress.prospring5.ch3.xml.InjectSimpleConfig" />
<Bean id = "injectSimpleSpel"
class = "com.apress.prospring5.ch3.xml.InjectSimpleSpel" t: name = "John
Mayer" t: edad = "39" t: height = "1.92" t: programador = "false" p: ageInSeconds =
"1241401112 "/> </ beans>
Se puede ver a partir de los dos fragmentos de código anteriores que es posible definir propiedades en el bean que aceptan Cuerda valores, valores
primitivos, o valores de envoltura primitivas y luego inyectar valores de estas propiedades mediante el uso de la < valor> etiqueta. Aquí está la salida creado
mediante la ejecución de este ejemplo como se esperaba:
67
Capítulo 3 ■ La introducción de la COI y Di en primavera
Para la inyección de valor simple de estilo de anotación, podemos aplicar el @ Valor anotación a las propiedades de frijol. Esta vez, en lugar del método de
selección, se aplica la anotación a la declaración de declaración de propiedad, como podemos ver en el siguiente fragmento de código (primavera es compatible
con la anotación, ya sea en el método de selección o en las propiedades):
com.apress.prospring5.ch3.annotated paquete;
org.springframework.beans.factory.annotation.Value importación;
org.springframework.context.support.GenericXmlApplicationContext importación;
org.springframework.stereotype.Service importación;
ctx.close (); }
68
Capítulo 3 ■ La introducción de la COI y Di en primavera
Una característica de gran alcance introducido en la primavera 3 es el Lenguaje de Expresión primavera (SpEL). SpEL le permite evaluar una expresión
dinámica y luego lo utiliza en la primavera de Application Context. Puede utilizar el resultado para la inyección en los granos de la primavera. En esta
sección, echar un vistazo a cómo utilizar SpEL para inyectar propiedades de otros granos, utilizando el ejemplo de la sección anterior.
Supongamos ahora queremos exteriorizar los valores para ser inyectado en un grano de resorte en una clase de configuración, como se muestra en el siguiente
fragmento de código:
com.apress.prospring5.ch3.annotated paquete;
org.springframework.stereotype.Component importación;
Podemos entonces definir el grano en la configuración XML y utilizar SpEL para inyectar las propiedades del bean en el grano dependiente, como se
muestra en el siguiente fragmento de configuración:
<Habas ...>
<Bean id = "injectSimpleConfig"
class = "com.apress.prospring5.ch3.xml.InjectSimpleConfig" />
69
Capítulo 3 ■ La introducción de la COI y Di en primavera
<Bean id = "injectSimpleSpel"
class = "com.apress.prospring5.ch3.xml.InjectSimpleSpel" t: name = "# {}
injectSimpleConfig.name" t: edad = "# {injectSimpleConfig.age + 1}" t: height =
"# {injectSimpleConfig. altura}" t: programador = "# {}
injectSimpleConfig.programmer" p: ageInSeconds = "#
{injectSimpleConfig.ageInSeconds}"/> </ beans>
Tenga en cuenta que usamos el SpEL # { injectSimpleConfig.name} en referencia a la propiedad de la otra frijol. Para la edad, añadimos 1 al
valor del grano para indicar que podemos utilizar para manipular SpEL la propiedad como mejor nos parezca y lo inyecta en el grano dependiente.
Ahora podemos probar la configuración con el programa que se muestra en el siguiente fragmento de código:
com.apress.prospring5.ch3.xml paquete;
org.springframework.context.support.GenericXmlApplicationContext importación;
70
Capítulo 3 ■ La introducción de la COI y Di en primavera
ctx.close (); }}
Cuando se utiliza la inyección valor de estilo de anotación, sólo tenemos que sustituir las anotaciones de valor con las expresiones juego (ver el
siguiente fragmento de código):
com.apress.prospring5.ch3.annotated paquete;
org.springframework.beans.factory.annotation.Value importación;
org.springframework.context.support.GenericXmlApplicationContext importación;
org.springframework.stereotype.Service importación;
71
Capítulo 3 ■ La introducción de la COI y Di en primavera
ctx.close (); }}
com.apress.prospring5.ch3.annotated paquete;
org.springframework.stereotype.Component importación;
72
Capítulo 3 ■ La introducción de la COI y Di en primavera
Probando el programa producirá el mismo resultado. Usando SpEL, se puede acceder a los frijoles y las propiedades del muelle gestionados y manipularlos
para el uso de la aplicación por el apoyo de las características del lenguaje sofisticados y la sintaxis de la primavera.
Como ya se ha visto, es posible inyectar un grano a otro mediante el uso de la árbitro etiqueta. El siguiente fragmento de código muestra una clase que
expone una setter para permitir que un grano a inyectar:
com.apress.prospring5.ch3.xml paquete;
org.springframework.context.support.GenericXmlApplicationContext importación;
com.apress.prospring5.ch3.Oracle importación;
ctx.close (); }
Para configurar la primavera para inyectar un grano a otro, primero tiene que configurar dos granos: uno que será inyectada y uno a ser el blanco de
la inyección. Una vez hecho esto, sólo tiene que configurar la inyección mediante el uso de la etiqueta < ref> etiqueta en el grano de destino. El siguiente
fragmento de código muestra un ejemplo de esta configuración (archivo app-contexto-xml.xml):
<Habas ...>
73
Capítulo 3 ■ La introducción de la COI y Di en primavera
<Bean id = "injectRef"
class = "com.apress.prospring5.ch3.xml.InjectRef"> <property name
= "oráculo">
<Ref frijol = "oráculo" /> </
property> </ bean> </ beans>
Un punto importante a destacar es que el tipo que se inyecta no tiene que ser el tipo exacto definido en el objetivo; los tipos sólo
tienen que ser compatibles. Compatible significa que si el tipo declarado en el objetivo es una interfaz, el tipo inyectado debe implementar
esta interfaz. Si el tipo declarado es una clase, el tipo inyectado debe ser ya sea del mismo tipo o un subtipo. En este ejemplo, la InjectRef clase
define la setOracle ()
método para recibir una instancia de Oráculo, que es una interfaz, y el tipo inyectado es BookwormOracle, una clase que implementa Oráculo. Este es un punto que
causa confusión para algunos desarrolladores, pero en realidad es bastante simple. Inyección está sujeto a las mismas reglas de escritura que cualquier código Java,
por lo que el tiempo que usted está familiarizado con la forma de escribir obras de Java, la comprensión de la tipificación de la inyección es fácil.
En el ejemplo anterior, el ID del grano para inyectar se especifica mediante el atributo local de la
<Ref> etiqueta. Como se verá más adelante, en la sección “La comprensión de la haba de nombres”, se puede dar un grano más de un nombre para que pueda
referirse a ella usando una variedad de alias. Cuando se utiliza el atributo local, significa que el < ref> la etiqueta sólo se basa en la identificación del frijol y nunca
en cualquiera de sus alias. Por otra parte, la definición de frijol debe existir en el mismo archivo de configuración XML. Para inyectar un grano por cualquier
nombre o importar uno de los otros archivos de configuración XML, utilice el atributo de frijol de la < ref> etiquetar en lugar del atributo local. El siguiente fragmento
de código se muestra una configuración alternativa para el ejemplo anterior, el uso de un nombre alternativo para el bean inyectada:
<Habas ...>
<Bean id = "injectRef"
class = "com.apress.prospring5.ch3.xml.InjectRef"> <property name
= "oráculo">
<Ref frijol = "wiseworm" /> </
property> </ bean> </ beans>
En este ejemplo, la oráculo bean se da un alias mediante el uso de la nombre atributo, y luego se inyecta en el injectRef bean mediante el uso de
este alias en conjunción con el atributo de frijol de la < ref> etiqueta. No se preocupe demasiado acerca de la semántica de nombres en este momento.
Discutimos esto en mucho más detalle más adelante en el capítulo. Ejecución de la InjectRef clase otra vez produce el mismo resultado que el ejemplo
anterior.
74
Capítulo 3 ■ La introducción de la COI y Di en primavera
Hasta ahora, los granos que han sido la inyección se han localizado en el mismo Application Context ( y por lo tanto la misma BeanFactory) como los
granos que se inyectan en. Sin embargo, Spring soporta una estructura jerárquica para
Application Context de modo que uno de contexto (y por lo tanto el asociar BeanFactory) se considera el padre de otro. Al permitir ApplicationContexts a
anidar, Primavera le permite dividir la configuración en diferentes archivos, que es un regalo del cielo en proyectos más grandes con una gran
cantidad de granos.
Al anidar Application Context casos, Primavera permite frijoles en lo que se considera el contexto niño para hacer referencia a los granos en el
contexto de los padres. Application Context anidación usando GenericXmlApplicationContext
es sencillo de entender. Para anidar una GenericXmlApplicationContext dentro de otro, simplemente llame al
setParent () método en el que el niño Application Context, como se muestra en el siguiente ejemplo de código:
com.apress.prospring5.ch3 paquete;
org.springframework.context.support.GenericXmlApplicationContext importación;
child.close ();
parent.close (); }}
com.apress.prospring5.ch3 paquete;
75
Capítulo 3 ■ La introducción de la COI y Di en primavera
Dentro del archivo de configuración para el niño Application Context, hace referencia a un frijol en el padre
Application Context funciona exactamente igual que hace referencia a un grano en el niño Application Context, a menos que tenga un grano en el
niño Application Context que comparte el mismo nombre. En ese caso, sólo tiene que reemplazar el atributo del frijol árbitro con elemento padre, y
usted está en su camino. El siguiente fragmento de configuración muestra el contenido del archivo de configuración para el padre BeanFactory, llamado
padre-context.xml:
<Habas ...>
<Bean id = clase "childTitle" = "java.lang.String" c: _0 = "hijas" />
Como se puede ver, esta configuración simplemente define dos granos: childTitle y parentTitle. Ambos son
Cuerda los objetos con los valores hijas y Gravedad. El siguiente fragmento de configuración representa la configuración para el
niño Application Context que está contenida en niño-context.xml:
<Habas ...>
<Bean id = clase "childTitle" = "java.lang.String" c: _0 = "No hay tal cosa" /> </ beans>
Tenga en cuenta que hemos definido cuatro granos de aquí. childTitle en este código es similar a childTitle en el padre, excepto que el Cuerda
que representa tiene un valor diferente, lo que indica que se encuentra en el niño
Application Context.
los song1 bean está utilizando el bean árbitro atribuir a hacer referencia al bean llamado parentTitle. Debido a que este frijol sólo existe en la
matriz BeanFactory, song1 recibe una referencia a ese bean. Hay dos puntos de interés aquí. En primer lugar, puede utilizar el atributo de frijol para
hacer referencia a los granos, tanto en el niño y el padre
Application Context s. Esto hace que sea fácil hacer referencia a los granos de forma transparente, lo que le permite moverse entre los granos de archivos de
configuración como su aplicación crece. El segundo punto de interés es que no se puede utilizar el atributo local para referirse a los frijoles en la matriz Application
Context. Los cheques de intérprete XML para ver que el valor del atributo local, existe como un elemento válido en el mismo archivo, evitando que pueda ser
utilizado para hacer referencia a los granos en el contexto de los padres.
76
www.allitebooks.com
Capítulo 3 ■ La introducción de la COI y Di en primavera
los song2 bean está utilizando el bean árbitro atributo para hacer referencia a childTitle. Debido a que el frijol se define en tanto Application
Context s, la song2 bean recibe una referencia a childTitle en su propia
Application Context.
los Song3 bean está utilizando el < ref> etiqueta para referencia childTitle directamente en la matriz
Application Context. Porque Song3 está utilizando el atributo padre de la < ref> etiqueta, el childTitle instancia declaró en el niño Application
Context se ignora por completo.
Usted puede haber notado que, a diferencia song1 y song2, la Song3 frijol no está utilizando el pag espacio de nombres. Mientras que la pag espacio
de nombres proporciona atajos útiles, que no proporciona todas las capacidades que al utilizar etiquetas de propiedad, como referencia a un grano de los
etiquetas de espacio de nombres o de propiedad para definir sus granos, en lugar de la mezcla de estilos (a menos que sea absolutamente necesario).
Como era de esperar, la song1 y Song3 habas tanto obtener una referencia a los granos en la matriz
Application Context, mientras que el song2 frijol obtiene una referencia a un grano en el niño Application Context.
La inyección de Colecciones
A menudo, los granos deben tener acceso a las colecciones de objetos en lugar de sólo los granos o los valores individuales. Por lo tanto, no debería ser una
sorpresa que la primavera le permite inyectar una colección de objetos en una de sus granos. El uso de la colección es simple: elige cualquiera < la lista>, <map>,
<set>, o < puntales> para representar una Lista, mapa, Conjunto, o propiedades instancia, y luego se pasa en los elementos individuales del mismo modo que lo haría
con cualquier otra inyección. la < puntales> etiqueta permite solamente Cuerda s que se pasa como el valor, debido a que la propiedades clase permite sólo para los
valores de las propiedades que sean Cuerda s. Cuando se utiliza < la lista>, <map>, o < set> se puede utilizar cualquier etiqueta que desee cuando se inyectan en una
propiedad, incluso otra etiqueta de colección. Esto le permite pasar de una Lista de Mapa s, una
Mapa de Conjunto s, o incluso una Lista de Mapa s de Conjunto s de Lista s! El siguiente fragmento de código se muestra una clase que puede tener los cuatro tipos de
com.apress.prospring5.ch3.xml paquete;
org.springframework.context.support.GenericXmlApplicationContext importación;
77
Capítulo 3 ■ La introducción de la COI y Di en primavera
ejemplo CollectionInjection =
(CollectionInjection) ctx.getBean ( "injectCollection"); instance.displayInfo ();
ctx.close (); }
Ese es un montón de código, pero lo que realmente hace muy poco. los principal() método recupera una
CollectionInjection frijol de primavera y luego llama al displayInfo () método. Este método solo da salida a los contenidos de la Mapa, Propiedades,
establezca, y Lista instancias que se inyectarán de primavera. La configuración requerida para inyectar valores para cada una de las propiedades
en el CollectionInjection clase se representa a continuación, y el archivo de configuración se denomina App-contexto-xml.xml.
78
Capítulo 3 ■ La introducción de la COI y Di en primavera
También, observe la declaración de la Map <String, Object> propiedad. Para las versiones más recientes que JDK 5, la primavera también es
compatible con la inflexible Colección declaración y llevará a cabo la conversión de la configuración XML al tipo correspondiente especificada en
consecuencia.
<Habas ...>
<Bean id = "lyricHolder"
lass = "com.apress.prospring5.ch3.xml.LyricHolder" />
<Bean id = "injectCollection"
class = "com.apress.prospring5.ch3.xml.CollectionInjection"> <property name =
"mapa">
<Mapa>
En este código, se puede ver que hemos inyectado valores en los cuatro emisores expuestos en el
CollectionInjection clase. Para el mapa propiedad, hemos inyectado una Mapa instancia mediante el < mapa> etiqueta. Observe que cada entrada se especifica
utilizando un < entrada> tag, y cada uno tiene una Cuerda llave y luego un valor de entrada. Este valor de entrada puede ser cualquier valor que se puede inyectar en
una propiedad por separado; Este ejemplo muestra el uso de la
<Valor> y < ref> etiquetas para añadir un Cuerda valor y una referencia de frijol a la Mapa. los LyricHolder clase, que es del tipo de la lyricHolder
bean inyecta en el mapa en la configuración anterior, se representa aquí:
79
Capítulo 3 ■ La introducción de la COI y Di en primavera
com.apress.prospring5.ch3.xml paquete;
com.apress.prospring5.ch3.ContentHolder importación;
Para el accesorios propiedad, se utiliza el < puntales> etiqueta para crear una instancia de java.util.Properties y rellenarla usando <prop> etiquetas.
Tenga en cuenta que aunque el < prop> etiqueta está enchavetado de una manera similar a la
<Entry> etiqueta, sólo podemos especificar Cuerda valores para cada propiedad que va en la propiedades ejemplo.
También, para el < mapa> elemento hay una alternativa, la configuración más compacta usando el valor y
Valor de ref atributos, en lugar de la < valor> y < ref> elementos. los mapa declarado aquí es equivalente a la de la configuración
anterior:
<Entry key = "someValue" = "Es un viernes, que finalmente lo hizo" /> <clave de entrada = = /
"lyricHolder" "someBean" valor-ref> </ map> </ property>
Tanto el < la lista> y < set> etiquetas funcionan de la misma manera: se especifica cada elemento mediante el uso de cualquiera de las etiquetas de
valores individuales como < valor> y < ref> que se utilizan para inyectar un solo valor en una propiedad. En la configuración anterior, se puede ver que hemos
añadido una Cuerda valor y una referencia de frijol tanto a la
Lista y Conjunto instancias.
Aquí está la salida generada por el principal() método en la clase CollectionInjection. Como era de esperar, que se limita a enumerar los elementos
añadidos a las colecciones del archivo de configuración.
Mapa contenidos:
Valor: No puedo creer que tengo la oportunidad de ver su cara Valor: LyricHolder: {
'Usted es el DJ, voy a ser el conductor'}
contenido de la lista:
80
Capítulo 3 ■ La introducción de la COI y Di en primavera
Recuerde que con el < la lista>, <map>, y < set> elementos, se puede emplear cualquiera de las etiquetas que se utilizan para establecer el valor de las
propiedades no cobro para especificar el valor de una de las entradas de la colección. Este es un concepto muy poderoso porque usted no está limitado sólo para
la inyección de colecciones de valores primitivos; también se puede inyectar colecciones de granos u otras colecciones.
El uso de esta funcionalidad, es mucho más fácil de modularizar su solicitud y proporcionar diferentes implementaciones, userselectable de piezas clave
de la lógica de la aplicación. Considere un sistema que permite al personal de las empresas para crear, corregir, y ordenar su negocio de papelería
personalizada en línea. En este sistema, la obra acabada para cada orden se envía a la impresora adecuada cuando está listo para la producción. La única
complicación es que algunas impresoras quieren recibir la obra a través de correo electrónico, algunos a través de FTP, y otras personas que utilizan Secure
Copy Protocol (SCP). Utilizando la inyección de la colección de primavera, se puede crear una interfaz estándar para esta funcionalidad, como se muestra en el
siguiente fragmento de código:
com.apress.prospring5.ch3 paquete;
En el ejemplo anterior, el Recipiente clase es una clase vacía. Desde esta interfaz, puede crear múltiples implementaciones, cada uno de los cuales
es capaz de describir en sí a un ser humano, como el que se muestra a continuación:
com.apress.prospring5.ch3 paquete;
@Anular
sendArtwork pública vacío (String artworkPath, receptor destinatario) {
// ftp lógica aquí ...}
@Anular
Cadena getFriendlyName pública () {
volver "File Transfer Protocol"; }
@Anular
Cadena getShortName pública () {
volver "ftp"; }}
Imagine que luego desarrolla una ArtworkManager clase que es compatible con todas las implementaciones disponibles de la Obra-remitente interfaz.
Con las implementaciones en su lugar, sólo tiene que pasar una Lista para usted
ArtworkManager clase, y usted está en su camino. Utilizando la getFriendlyName () método, se puede mostrar una lista de opciones de entrega
para el administrador del sistema para elegir cuando se está configurando cada plantilla de papelería. Además, su aplicación puede permanecer
totalmente desacoplado de las implementaciones individuales si sólo código para el ArtworkSender interfaz. Vamos a salir de la aplicación de la ArtworkManag
clase como un ejercicio para usted.
81
Capítulo 3 ■ La introducción de la COI y Di en primavera
Además de la configuración de XML, puede utilizar las anotaciones para inyección colección. Sin embargo, también le gustaría externalizar los
valores de las colecciones en el archivo de configuración para un fácil mantenimiento. El siguiente fragmento es la configuración de cuatro granos de
resorte diferentes que imitan las mismas propiedades de la colección de la muestra anterior (archivo de configuración app-contexto-annotation.xml):
<Context: componente-scan
base paquete = "com.apress.prospring5.ch3.annotated" />
También vamos a desarrollar una versión de la anotación LyricHolder clase. El contenido de clase se representa aquí:
com.apress.prospring5.ch3.annotated paquete;
com.apress.prospring5.ch3.ContentHolder importación;
org.springframework.stereotype.Service importación;
@Service ( "lyricHolder")
clase pública implementa LyricHolder ContentHolder {
82
Capítulo 3 ■ La introducción de la COI y Di en primavera
Valor de la cadena privada = "" Usted sea el DJ, voy a ser el conductor";
En la configuración representada anteriormente, hacemos uso de la util espacio de nombres proporcionada por el resorte de declarar sus granos para
almacenar propiedades de la colección: la util espacio de nombres. Se simplifica en gran medida la configuración, en comparación con las versiones anteriores de
la primavera. En la clase se utiliza para probar la configuración, inyectamos las habas y uso previo de la JSR-250 @ Recurso anotación con el nombre especificado
como un argumento para identificar correctamente los granos. los displayInfo () método es el mismo que antes, así que ya no se muestra aquí.
privada establecida;
ctx.close (); }
...
}
Ejecutar el programa de pruebas, y obtendrá el mismo resultado que la muestra utilizando la configuración de XML.
83
Capítulo 3 ■ La introducción de la COI y Di en primavera
Usted puede preguntarse por qué la anotación @ Recurso se utiliza en lugar de @ Autowired. Es debido a que la
@Autowired anotación se define semánticamente de una manera que siempre trata a arrays, colecciones y mapas como conjuntos de granos
correspondientes, con el tipo de frijol diana derivado del tipo de valor de la colección declarado. Así, por ejemplo, si una clase tiene un atributo de
tipo Lista <ContentHolder> y tiene la @ Autowired anotación definida, Primavera trate de inyectar todos los granos de tipo ContentHolder dentro de la
corriente Application Context en ese atributo (en lugar de la < util: lista> declarado en el archivo de configuración), lo que resultará en cualquiera de las
dependencias inesperados que se inyecta o primavera lanzar una excepción si no bean de tipo ContentHolder
Fue definido. Por lo tanto, para la inyección de tipo de colección, tenemos que instruir explícitamente primavera para llevar a cabo la inyección
Una combinación de @ Autowired y @ Índice Se puede utilizar para cumplir con el mismo propósito, pero siempre es preferible utilizar una
anotación y no dos. En el siguiente fragmento de código, se puede ver la configuración equivalente a inyectar una colección utilizando su nombre de frijol
com.apress.prospring5.ch3.annotated paquete;
org.springframework.beans.factory.annotation.Autowired importación;
org.springframework.beans.factory.annotation.Qualifier importación; @Service (
"injectCollection") public class {CollectionInjection
@Autowired
@Qualifier ( "mapa")
Además constructor y la inyección de setter, otra característica DI menos frecuentemente utilizado que Spring proporciona es
Inyección método. Método capacidades de inyección de primavera vienen en dos formas vagamente relacionados, Método de búsqueda de inyección y
de reemplazo Método. Lookup Método Inyección proporciona otro mecanismo por el que un grano puede obtener una de sus dependencias. Método de
sustitución le permite reemplazar la aplicación de cualquier método en un grano de forma arbitraria, sin tener que cambiar el código fuente original. Para
proporcionar estas dos características, Spring utiliza las capacidades de mejora de bytecode dinámicos de CGLIB. 3
3 cglib es un potente y de alto rendimiento, y la biblioteca de generación de código de alta calidad. Además, puede extenderse clases Java e implementar las interfaces en tiempo de
84
Capítulo 3 ■ La introducción de la COI y Di en primavera
Método de Inyección de búsqueda se añadió a la primavera en la versión 1.1 para superar los problemas encontrados cuando un grano de frijol depende de
otro con un ciclo de vida diferente, específicamente, cuando un conjunto unitario depende de un más de un elemento. En esta situación, tanto de la moda y el
constructor resultado de la inyección en el singleton mantener una única instancia de lo que debería ser un grano más de un elemento. En algunos casos,
tendrá que tener el grano Singleton obtener una nueva instancia de la cada vez más de un elemento que requiere el grano en cuestión.
Consideremos un escenario en el que una LockOpener clase proporciona el servicio de abrir cualquier vestuario. los
LockOpener clase se basa en una KeyHelper clase para abrir el armario, que se inyecta en LockOpener.
Sin embargo, el diseño de la KeyHelper clase implica algunos estados internos que lo hacen no aptos para su reutilización. Cada vez que el openLock
() método se llama, un nuevo KeyHelper Se requiere instancia. En este caso, LockOpener
será un producto único. Sin embargo, si inyectamos el KeyHelper clase utilizando el mecanismo normal, la misma instancia de la KeyHelper será
reutilizado clase (que se crea una instancia cuando la primavera realizó la inyección de la primera vez). Para asegurarse de que una nueva
instancia de la KeyHelper ejemplo se pasa a la openLock ()
método cada vez que se invoca, tenemos que utilizar la búsqueda Método de Inyección.
Por lo general, se puede lograr esto haciendo que el grano de implementar el singleton ApplicationContextAware
interfaz (hablamos de esta interfaz en el siguiente capítulo). Luego, utilizando la Application Context ejemplo, el grano de Singleton puede buscar una nueva
instancia de la dependencia más de un elemento cada vez que lo necesita. Método de Inyección de búsqueda permite que el grano de Singleton a declarar
que requiere una dependencia más de un elemento y que recibirá una nueva instancia del bean de más de un elemento cada vez que tiene que interactuar
con él, sin necesidad de aplicar ninguna interfaz de primavera-específica.
trabajos de inyección de búsqueda de métodos por tener su Singleton declarar un método, el método de búsqueda, que devuelve una instancia del
bean de más de un elemento. Al obtener una referencia al producto único en su aplicación, en realidad se está recibiendo una referencia a una subclase
creado de forma dinámica en la que la primavera ha implementado el método de búsqueda. Una aplicación típica implica la definición del método de
búsqueda, y por lo tanto la clase de bean, como abstracta. Esto evita cualquier error extraños se filtren en cuando se olvida de configurar la inyección
Método y que están trabajando directamente en contra de la clase de bean con la implementación del método vacía en lugar de la subclase
Primavera-mejorada. Este tema es bastante complejo y se muestra mejor con el ejemplo.
En este ejemplo, creamos un grano más de un elemento y dos granos simples que tanto implementar la misma interfaz. Uno de los singletons
obtiene una instancia de la haba de más de un elemento mediante el uso de inyección “tradicional” setter; el otro utiliza el método de inyección. El
siguiente ejemplo de código muestra el Cantante clase, que en este ejemplo es el tipo de la haba de más de un elemento:
com.apress.prospring5.ch3 paquete;
Esta clase es decididamente poco atractiva, pero sirve a los propósitos de este ejemplo a la perfección. A continuación, se puede ver la DemoBean interfaz,
que se implementa por tanto de las clases de frijol únicos.
85
Capítulo 3 ■ La introducción de la COI y Di en primavera
Este bean tiene dos métodos: getMySinger () y hacer algo(). La aplicación de ejemplo utiliza el
getMySinger () método para obtener una referencia a la Cantante instancia y, en el caso de la haba de búsqueda método, para realizar las operaciones de
búsqueda método real. los hacer algo() método es un método sencillo que depende de la
Cantante clase haga su procesamiento. El siguiente fragmento de código muestra la StandardLookupDemoBean clase, que utiliza una inyección de setter
para obtener una instancia de la Cantante clase:
com.apress.prospring5.ch3 paquete;
@Anular
El cantante pública getMySinger () {
volver this.mySinger; }
@Anular
doSomething public void () {
mySinger.sing (); }}
todo este código debería ser familiar, pero notar que la hacer algo() método utiliza la instancia almacenada de
Cantante para completar su tratamiento. En el siguiente fragmento de código, se puede ver la AbstractLookupDemoBean
clase, que utiliza el método de inyección para obtener una instancia de la Cantante clase.
com.apress.prospring5.ch3 paquete;
@Anular
doSomething public void () {
getMySinger () cantar ().; }}
Observe que el getMySinger () método se declara como abstracto y que este método es llamado por el
hacer algo() método para obtener una Cantante ejemplo. La configuración XML de Spring para este ejemplo está contenida en un archivo
llamado App-contexto-xml.xml y se muestra aquí:
<Habas ...>
<Bean id = clase "cantante" = "com.apress.prospring5.ch3.Singer"
scope = "prototipo" />
86
Capítulo 3 ■ La introducción de la COI y Di en primavera
<Bean id = "abstractLookupBean"
class => <lookup-método "com.apress.prospring5.ch3.AbstractLookupDemoBean"
name = "getMySinger" grano = "cantante" /> </ bean>
<Bean id = "standardLookupBean"
class = "com.apress.prospring5.ch3.StandardLookupDemoBean"> <property name =
"mySinger" ref = "cantante" /> </ bean> </ beans>
La configuración para el cantante y standardLookupBean granos deben resultar familiar a usted por ahora. por abstracto-LookupBean, es necesario
configurar el método de búsqueda mediante el uso de la etiqueta < lookup-method> etiqueta. los
nombre atributo de la < lookup-method> Primavera etiqueta le dice el nombre del método en el grano que debe pasar por encima. Este método no debe
aceptar ningún argumento, y el tipo de retorno debe ser el del frijol que desea devolver a partir del método. En este caso, el método debe devolver
una clase de tipo Cantante, o de sus subclases. El atributo de frijol de primavera, que dice frijol el método de búsqueda debe devolver. El siguiente
fragmento de código se muestra la pieza final del código para este ejemplo, que es la clase que contiene la principal() método utiliza para ejecutar el
ejemplo:
com.apress.prospring5.ch3 paquete;
org.springframework.context.support.GenericXmlApplicationContext importación;
org.springframework.util.StopWatch importación;
ctx.close (); }
87
Capítulo 3 ■ La introducción de la COI y Di en primavera
stopWatch.stop ();
Para el abstractLookupBean haba, una nueva instancia de Cantante debe ser recuperada para cada llamada a
getMySinger (), por lo que las referencias no deben ser los mismos.
por standardLookupBean, una única instancia de Cantante se pasa al frijol por inyección organismo, y este caso se almacena y se devuelve
para cada llamada a getMySinger (), por lo que las dos referencias deben ser los mismos.
la Cronógrafo clase utilizada en el ejemplo anterior es una clase de utilidad disponible con la primavera. Encontrarás
Cronógrafo muy útil cuando se necesita para llevar a cabo pruebas de rendimiento simples y cuando se está probando sus aplicaciones.
La parte final de la displayInfo () método se ejecuta una prueba de funcionamiento sencillo para ver cuál es más rápido frijol. Claramente, standardLookupBean
debe ser más rápido porque devuelve la misma instancia cada vez, pero es interesante ver la diferencia. Ahora podemos ejecutar el LookupDemo clase
para la prueba. Aquí está la salida que recibimos de este ejemplo:
Como se puede ver, el Cantante Las instancias son, como se esperaba, el mismo cuando usamos standardLookupBean y diferente cuando
usamos abstractLookupBean. Hay una diferencia notable en el rendimiento cuando se utiliza
standardLookupBean, pero eso es de esperar.
Por supuesto, hay una manera equivalente a configurar los granos presentados anteriormente utilizando anotaciones. los
cantante bean debe tener una anotación adicional para especificar el prototipo alcance.
com.apress.prospring5.ch3.annotated paquete;
88
Capítulo 3 ■ La introducción de la COI y Di en primavera
org.springframework.context.annotation.Scope importación;
org.springframework.stereotype.Component importación;
@Component ( "cantante)
@Scope (" prototipo ") Singer
public class {
Cadena lírica privada = "He jugado un juego rápido de ajedrez
con la sal y la pimienta agitador ";
los AbstractLookupDemoBean de clases ya no es una clase abstracta, y el método getMySinger () tiene un cuerpo vacío y está
anotado con @ Buscar que recibe como argumento el nombre de la Cantante frijol. El cuerpo del método será anulado, en la subclase
generado dinámicamente.
com.apress.prospring5.ch3.annotated paquete;
org.springframework.beans.factory.annotation.Lookup importación;
org.springframework.stereotype.Component importación;
@Component ( "abstractLookupBean")
clase pública implementa AbstractLookupDemoBean DemoBean {
@Lookup ( "cantante")
El cantante pública getMySinger () {
nula regresar; // anulado dinámicamente}
@Anular
doSomething public void () {
getMySinger () cantar ().; }}
los StandardLookupDemoBean única clase debe ser anotado con @ Componente, y setMySinger debe ser anotado con @ Autowired
y @ Índice para inyectar el cantante frijol.
com.apress.prospring5.ch3.annotated paquete;
org.springframework.beans.factory.annotation.Autowired importación;
org.springframework.beans.factory.annotation.Qualifier importación;
org.springframework.stereotype.Component importación;
@Component ( "standardLookupBean")
clase pública implementa StandardLookupDemoBean DemoBean {
89
Capítulo 3 ■ La introducción de la COI y Di en primavera
@Autowired
@Qualifier ( "cantante")
setMySinger pública vacío (Singer mySinger) {
this.mySinger = mySinger; }
@Anular
El cantante pública getMySinger () {
volver this.mySinger; }
@Anular
doSomething public void () {
mySinger.sing (); }}
El archivo de configuración, el nombre App-contexto-annotated.xml, sólo se debe activar el análisis de componentes para el paquete que
contiene las clases anotadas.
<Habas ...>
<Context: componente-scan
base paquete = "com.apress.prospring5.ch3.annotated" />
</ Beans>
La clase se utiliza para ejecutar el código es idéntico a la clase LookupDemo; la única diferencia es el archivo XML utilizado como un
argumento para crear el GenericXmlApplicationContext objeto.
Si queremos deshacernos de archivos XML totalmente, esto se puede hacer usando una clase de configuración para activar el análisis del
componente en el com.apress.prospring5.ch3.annotated paquete. Y esta clase puede ser declarado justo donde lo necesita, es decir, en este caso
dentro de la clase que se ejecuta para probar los granos, como se muestra aquí:
com.apress.prospring5.ch3.config paquete;
com.apress.prospring5.ch3.annotated.DemoBean importación;
com.apress.prospring5.ch3.annotated.Singer importación;
org.springframework.context.annotation.AnnotationConfigApplicationContext importación;
org.springframework.context.annotation.ComponentScan importación;
org.springframework.context.annotation.Configuration importación;
org.springframework.context.support.GenericApplicationContext importación; org.springframework.util.StopWatch
importación;
java.util.Arrays de importación;
@Configuración
@ComponentScan (basePackages = { "com.apress.prospring5.ch3.annotated"}) LookupConfig
clase public static {}
90
Capítulo 3 ■ La introducción de la COI y Di en primavera
ctx.close (); }
configuraciones alternativas utilizando anotaciones y configuración Java se tratan en más detalle en el capítulo 4 .
Método de Inyección de búsqueda es para uso cuando se quiere trabajar con dos granos de diferentes ciclos de vida. Evitar la tentación de utilizar la
búsqueda Método de inyección cuando los granos comparten el mismo ciclo de vida, sobre todo si son únicos. La salida de ejecutar el ejemplo anterior
muestra una diferencia notable en el rendimiento entre usando el Procedimiento de inyección para obtener nuevas instancias de una dependencia y el uso
de DI estándar para obtener una sola instancia de una dependencia. Además, asegúrese de que no utilice el método de búsqueda de inyección sin
necesidad, incluso cuando se tiene granos de diferentes ciclos de vida.
Considere una situación en la que tiene tres hijos únicos que comparten una dependencia en común. Desea que cada producto único que
tiene su propia instancia de la dependencia, por lo que se crea la dependencia como más de un elemento, pero usted es feliz con cada producto
único con la misma instancia del colaborador lo largo de su vida. En este caso, la inyección de setter es la solución ideal; Método de Inyección de
búsqueda sólo añade una sobrecarga innecesaria.
Cuando se utiliza el método de búsqueda de inyección, hay algunas pautas de diseño que usted debe tener en cuenta en la construcción de sus
clases. En los ejemplos anteriores, declaramos el método de búsqueda en una interfaz. La única razón por la que hicimos esto fue que no tuvimos que
duplicar la displayInfo () método de dos veces por dos tipos de frijol diferentes. Como se mencionó anteriormente, en general, no es necesario para
contaminar una interfaz de negocios con las definiciones innecesarias que se utilizan únicamente con fines COI. Otro punto es que a pesar de que no
tiene que hacer que su método de búsqueda abstracta, haciendo así que le impide olvidar para configurar el método de búsqueda y luego usando una
aplicación en blanco por accidente. Por supuesto, esto sólo funciona con configuración XML. configuración basada en anotación obliga a una
aplicación vacío del método; de lo contrario, no se creará el bean.
91
Capítulo 3 ■ La introducción de la COI y Di en primavera
reemplazo método
Aunque la documentación de Primavera clasifica reemplazo método como una forma de inyección, es diferente de lo que hemos visto hasta ahora. Hasta
ahora, hemos utilizado la inyección puramente para suministrar los granos con sus colaboradores. Utilizando el método de sustitución, se puede sustituir la
aplicación de cualquier método de cualquier habas arbitrariamente sin tener que cambiar la fuente del grano que se está modificando. Por ejemplo, usted
tiene una biblioteca de terceros que se utiliza en la aplicación de la primavera, y es necesario cambiar la lógica de un determinado método. Sin embargo, no
son capaces de cambiar el código fuente, ya que fue proporcionado por un tercero, por lo que una solución es utilizar el método de reemplazo simplemente
reemplazar la lógica para ese método con su propia aplicación.
Internamente, a lograr esto mediante la creación de una subclase de la clase de bean de forma dinámica. Se utiliza CGLIB y redirigir las
llamadas al método que desea reemplazar a otro bean que implementa el MethodReplacer
interfaz. En el siguiente ejemplo de código, se puede ver un grano simple que declara dos sobrecargas del
FormatMessage () método:
com.apress.prospring5.ch3 paquete;
Puede reemplazar cualquiera de los métodos en el ReplacementTarget clase utilizando la funcionalidad de reemplazo método de la
primavera. En este ejemplo, le mostramos cómo sustituir la FormatMessage (String)
método, y también comparar el rendimiento del método reemplazado a la de la original.
Para sustituir un método, primero tiene que crear una aplicación de la MethodReplacer interfaz; esto se muestra en el siguiente ejemplo
de código:
com.apress.prospring5.ch3 paquete;
org.springframework.beans.factory.support.MethodReplacer importación;
java.lang.reflect.Method importación;
@Anular
reimplementar pública de objetos (arg0 objeto, método Método, objeto ... args)
lanza Throwable {if
(isFormatMessageMethod (método)) {
Cadena msg = (String) args0; volver
"<h2>" + msg + "</ h2>"; } Else {
92
Capítulo 3 ■ La introducción de la COI y Di en primavera
return true; }}
los MethodReplacer interfaz tiene un único método, reimplementar (), que se debe aplicar. Tres argumentos se pasan
a reimplementar (): el grano en la que se invoca el método original, una
Método instancia que representa el método que se está anulado, y la matriz de argumentos pasados al método. los reimplementar () método
debe devolver el resultado de la lógica reimplantado, y, obviamente, el tipo del valor de retorno debe ser compatible con el tipo de
retorno del método que está reemplazando. En el ejemplo de código anterior, FormatMessageReplacer comprueba primero para ver si el
método que se está anulado es la FormatMessage (String) método; si es así, ejecuta la lógica de reposición (en este caso, que rodea el
mensaje con < h2> y </ h2>) y devuelve el mensaje formateado a la persona que llama. No es necesario comprobar si el mensaje es
correcto, pero esto puede ser útil si está utilizando unos pocos MethodReplacer s con argumentos similares. El uso de un cheque ayuda
a evitar una situación en la que un diferente
<Habas ...>
<Bean id = "methodReplacer"
class = "com.apress.prospring5.ch3.FormatMessageReplacer" />
<Bean id = "replacementTarget"
class = "com.apress.prospring5.ch3.ReplacementTarget"> <nombre-método reemplazado =
sustituto "FormatMessage" = "methodReplacer">
<Arg-type> cadena </ arg-type> </ método
reemplazado> </ bean>
<Bean id = "standardTarget"
class = "com.apress.prospring5.ch3.ReplacementTarget" /> </ beans>
93
Capítulo 3 ■ La introducción de la COI y Di en primavera
Como se puede ver, el MethodReplacer aplicación se declara como un grano en el Application Context.
A continuación, utiliza el < sustituido-method> etiqueta para sustituir el FormatMessage (String) método de
replacementTargetBean. El atributo nombre de la < sustituido-method> etiqueta especifica el nombre del método para sustituir, y el atributo
sustituto se utiliza para especificar el nombre de la MethodReplacer bean que queremos sustituir la implementación del método. En los casos
en que hay métodos tales como en el sobrecargado
ReplacementTarget clase, se puede utilizar el < arg-type> etiqueta para especificar la firma del método de igualar. los
<Arg-type> tag apoya coincidencia de patrones, por lo Cuerda está adaptada a java.lang.String y también para Java. lang.StringBuffer.
El siguiente fragmento de código muestra una aplicación de demostración simple que recupera tanto el standardTarget
y reemplazo de destino habas de Application Context, ejecuta su FormatMessage (String)
métodos y, a continuación, se ejecuta una prueba de funcionamiento sencillo para ver cuál es más rápido.
com.apress.prospring5.ch3 paquete;
org.springframework.context.support.GenericXmlApplicationContext importación;
org.springframework.util.StopWatch importación;
ctx.close (); }
stopWatch.stop ();
94
Capítulo 3 ■ La introducción de la COI y Di en primavera
Debe estar familiarizado con este código por ahora, así que no voy a entrar en detalle. En nuestra máquina, de ejecutar este ejemplo se obtiene el
siguiente resultado:
Como era de esperar, la salida de la replacementTarget frijol refleja la aplicación que el reemplazado Método-Sustituto proporciona. Curiosamente,
sin embargo, el método dinámicamente sustituido es muchas veces más lento que el método estáticamente definido. Extracción del cheque por un método
válido en MethodReplacer hecho una diferencia insignificante a través de una serie de ejecuciones, por lo que podemos concluir que la mayor parte de los
gastos generales es de la subclase CGLIB.
reemplazo método puede resultar muy útil en una variedad de circunstancias, especialmente cuando se desea anular solamente un método particular para
un solo grano en lugar de todos los granos del mismo tipo. Dicho esto, seguimos prefiriendo utilizar los mecanismos estándar de Java para sobrescribir los
métodos en lugar de en función de la mejora de tiempo de ejecución de código de bytes.
Si se va a utilizar el reemplazo método como parte de su solicitud, le recomendamos que utilice uno Método-Sustituto por
método o grupo de métodos sobrecargados. Evitar la tentación de utilizar un único
MethodReplacer para las porciones de los métodos no relacionadas; esto da lugar a las comparaciones de cadenas innecesarios adicionales, mientras que
su código funciona qué método debe reimplementar. Hemos encontrado que la realización de controles simples para asegurarse de que MethodReplacer está
trabajando con el método correcto es útil y no agrega demasiado trabajo a su código. Si está realmente preocupado por el rendimiento, simplemente puede
añadir una propiedad booleana a su MethodReplacer, que le permite girar el cheque y se apaga mediante la inyección de dependencia.
de identidad atributo, el valor de ese atributo se utiliza como el nombre. Si no carné de identidad
atributo se especifica, Primavera busca una nombre atributo, y si uno está definido, se utiliza el primer nombre definido en el nombre atributo.
(Decimos el primer nombre, ya que es posible definir varios nombres dentro de la nombre
atributo; Esto se explica en más detalle en breve.) Si ni el carné de identidad ni el nombre atributo se especifica, Primavera utiliza nombre de la clase del
bean como el nombre, siempre, por supuesto, que ningún otro frijol está utilizando el mismo nombre de la clase. Si se declaran múltiples granos del
mismo tipo sin un ID o nombre, la primavera va a lanzar una excepción (de tipo org.springframework.beans.factory.NoSuchBeanDefinitionException) en la
inyección durante
Application Context inicialización. La siguiente configuración de ejemplo de configuración representa los tres esquemas de nombramiento ( app-contexto-01.xml):
<Habas ...>
<Bean id = clase "cadena1" = "java.lang.String" /> <bean name =
clase "string2" = "java.lang.String" /> <clase bean =
"java.lang.String" /> < / beans>
95
Capítulo 3 ■ La introducción de la COI y Di en primavera
Cada uno de estos enfoques es igualmente válido desde un punto de vista técnico, pero que es la mejor opción para su aplicación? Para empezar,
evitar el uso de la denominación automática por el comportamiento de la clase. Esto no le permite mucha flexibilidad para definir múltiples granos del
mismo tipo, y es mucho mejor para definir sus propios nombres. De esta manera, si la primavera cambia el comportamiento predeterminado en el futuro, su
aplicación sigue trabajando. Si desea ver cómo la primavera es nombrar los granos, utilizando la configuración anterior, ejecute el siguiente ejemplo:
com.apress.prospring5.ch3.xml paquete;
org.springframework.context.support.GenericXmlApplicationContext importación;
ctx.close (); }}
ctx.getBeansOfType (String.class) se utiliza para obtener un mapa con todos los granos de tipo Cuerda y sus documentos de identidad que
existen dentro de Application Context. Las llaves del mapa son los ID de frijol que se imprimen con la expresión lambda en el código anterior. Con
la configuración mencionada, esto es la salida:
cadena1
cadena2
java.lang.String # 0
La última línea en la muestra de salida anterior es el ID que la primavera dio al bean de tipo Cuerda que no fue nombrado
explícitamente en la configuración. Si la configuración se modifica para añadir otro Cuerda
frijol sin nombre, que se vería así:
<Habas ...>
<Bean id = clase "cadena1" = "java.lang.String" /> <bean name =
clase "string2" = "java.lang.String" /> <clase bean =
"java.lang.String" /> < frijol class = "java.lang.String" /> </ beans>
cadena1
cadena2
java.lang.String # 0
java.lang.String # 1
96
Capítulo 3 ■ La introducción de la COI y Di en primavera
Con anterioridad a la primavera 3.1, el carné de identidad atributo es la misma que la identidad XML (es decir, xsd: ID), lo que sitúa una restricción en los caracteres
que puede utilizar. A partir de la primavera 3,1, utiliza Spring xsd: string Para el carné de identidad atribuir, por lo que la restricción anterior sobre los caracteres que se
pueden utilizar se ha ido. Sin embargo, la primavera seguirá garantizando que la carné de identidad es único en todo el Application Context. Como práctica general, usted
debe dar su grano de un nombre mediante el uso de la carné de identidad atribuir y luego asociar el grano con otros nombres mediante el uso de nombre de aliasing, como
<Habas ...>
<Bean id = "john" name = "john johnny, Jonathan; jim" class = "java.lang.String" /> <alias name = "john"
alias = "ion" /> </ beans>
Como se puede ver, se han definido seis nombres: uno usando el carné de identidad atributo y los otros cuatro como una lista con todos los
delimitadores nombre del bean permitidos en el nombre atributo (esto es sólo para fines de demostración y no se recomienda para el desarrollo de la
vida real). En el desarrollo de la vida real, se recomienda estandarizar el delimitador a usar para separar las declaraciones nombres de frijol dentro de
su aplicación. Uno más alias se definió utilizando la < alias> etiqueta. El siguiente ejemplo de código muestra una rutina de Java que se agarra a la
misma desde el frijol Application Context instancia de seis veces usando diferentes nombres y verifica que ellos son los mismos frijol. Además, se hace
uso del presentado anteriormente ctx.getBeansOfType (..) método para asegurarse de que sólo hay una Cuerda frijol en el contexto.
com.apress.prospring5.ch3.xml paquete;
org.springframework.context.support.GenericXmlApplicationContext importación;
java.util.Map importación;
97
Capítulo 3 ■ La introducción de la COI y Di en primavera
si (beans.size () == 1) {
System.out.println ( "Sólo hay una Cadena de frijol."); }
ctx.close (); }}
Ejecutar el código anterior se imprimirá cierto cinco veces y la “Sólo hay un Hilo” texto, la verificación de que los granos de
acceder usando diferentes nombres son, de hecho, el mismo frijol.
Puede recuperar una lista de los alias bean llamando ApplicationContext.getAliases (String) y que pasa en cualquiera de los nombres o
identificadores de los granos. La lista de alias, que no sea el que se especifica, que se obtiene es una Cuerda formación.
Se mencionó antes que con anterioridad a la primavera del 3,1 carné de identidad atributo es la misma que la identidad XML (es decir, xsd: ID), lo que significa que
los ID de frijol no podían contener caracteres especiales como el espacio-, comas o punto y coma. A partir de la primavera 3,1, xsd: string se utiliza para la carné de
identidad atribuir, por lo que la restricción anterior sobre los caracteres que se pueden utilizar se ha ido. Sin embargo, esto no quiere decir que usted puede utilizar lo
siguiente:
en lugar de esto:
los nombre y carné de identidad valores de los atributos son tratados de manera diferente por el COI de primavera. Puede recuperar una lista de los
alias bean llamando ApplicationContext.getAliases (String) y que pasa en cualquiera de los nombres o identificadores de los granos. La lista de alias, que no
sea el que se especifica, que se obtiene es una Cuerda formación. Esto significa, en el primer caso, Jon se convertirá en la identificación, y el resto de valores
se convertirá alias.
En el segundo caso, cuando la misma cadena se utiliza como un valor para la carné de identidad atribuir, la cadena completa se convierte en un identificador único
para el grano. Esto se puede ensayar fácilmente con una configuración como la que se muestra aquí (que se encuentra en el archivo app-contexto-03.xml):
<Habas ...>
<Nombre de bean = "Jon johnny, Jonathan; jim" class = "java.lang.String" />
<Bean id = "Jon johnny, Jonathan; jim" class = "java.lang.String" /> </ beans>
com.apress.prospring5.ch3.xml paquete;
org.springframework.context.support.GenericXmlApplicationContext importación;
java.util.Arrays de importación;
java.util.Map importación;
98
Capítulo 3 ■ La introducción de la COI y Di en primavera
ctx.close (); }}
ID: Jon
alias: Jonathan, jim, johnny
Como se puede ver, el mapa con Cuerda frijol contiene dos granos, uno con el Jon identificador único y tres alias y uno con
el Jon johnny, Jonathan; jim identificador único y no hay alias.
Frijol nombre de alias es una bestia extraña, ya que no es algo que tiende a utilizar cuando se está construyendo una nueva aplicación. Si usted
va a tener muchos otros granos inyectan otro bean, pueden también utilizar el mismo nombre para acceder a esa frijol. Sin embargo, como su aplicación
entra en trabajo de producción y mantenimiento se deja llevar a cabo, se realizan modificaciones, y así sucesivamente, nombre del bean aliasing se
vuelve más útil.
Considere el siguiente escenario: tiene una aplicación en la que 50 frijoles, configuran utilizando la primavera, todos requieren una
implementación de la foo interfaz. Veinticinco de los granos de usar el StandardFoo
aplicación con el nombre de frijol standardFoo, y el otro 25 utiliza el SuperFoo aplicación con el SuperFoo nombre del bean. Seis
meses después de poner la aplicación en producción, decide mover los primeros 25 habas a la SuperFoo implementación. Para
ello, usted tiene tres opciones.
• La segunda opción es actualizar la configuración de inyección para los 25 granos que están cambiando, que
cambia los nombres de las habas de standardFoo a SuperFoo. Este enfoque no es la forma más elegante para
proceder. Se podría realizar una búsqueda y reemplazo, pero luego revertir los cambios cuando la administración
no es feliz significa recuperar una versión antigua de la configuración de su sistema de control de versiones.
• La tercera, y más ideal, enfoque consiste en quitar (o fuera) de la definición de la standardFoo frijol y
hacer standardFoo un alias SuperFoo. Este cambio requiere un mínimo esfuerzo, y restaurar el
sistema a su configuración anterior es tan simple.
99
Capítulo 3 ■ La introducción de la COI y Di en primavera
Cuando las definiciones de frijol se declaran mediante anotaciones, nombres de frijol es un poco diferente de XML, y hay cosas más interesantes que se
pueden hacer. Vamos a empezar con lo básico, sin embargo: declarar definiciones de frijol utilizando anotaciones estereotipo (@ Componente y todas
sus especialidades, tales como Servicio, depósito, y
Controlador).
Considera lo siguiente Cantante clase:
com.apress.prospring5.ch3.annotated paquete;
org.springframework.stereotype.Component importación;
@Componente
Cadena lírica privada = "Hemos encontrado un mensaje en una botella que estábamos bebiendo";
Esta clase contiene la declaración de un grano de tipo singleton Cantante escrita con las teclas @ Componente
anotación. Los @ Componente anotación no tiene ningún argumento, por lo que el contenedor de primavera IoC decide un identificador único para el grano.
La convención utilizada en este caso es nombrar el grano, como la propia clase, pero la conversión a minúsculas la primera letra. Esto significa que el grano
será nombrado cantante. Esta convención es respetado por otras anotaciones estereotipo también. Para probar esto, la clase puede utilizarse el siguiente:
com.apress.prospring5.ch3.annotated paquete;
org.springframework.context.support.GenericXmlApplicationContext importación;
java.util.Arrays de importación;
java.util.Map importación;
100
Capítulo 3 ■ La introducción de la COI y Di en primavera
los App-contexto-annotated.xml archivo de configuración contiene solamente una declaración de exploración componente para com.apress.prospring5.ch3.anno
por lo que no se mostrará de nuevo. Cuando se ejecuta la clase anterior, la siguiente salida se imprime en la consola:
ID: cantante
Por lo tanto, el uso de @ Componente ( "cantante") es equivalente a la anotación de la Cantante clase con @ Componente. Si desea asignar un nombre
diferente del frijol, el @ Componente anotación debe recibir el nombre del bean como un argumento.
com.apress.prospring5.ch3.annotated paquete;
org.springframework.stereotype.Component importación;
Cadena lírica privada = "Abajo hay debajo de nosotros, bajo las nubes";
Pero, ¿qué pasa con los alias? A medida que el argumento a favor de la @ Componente anotación se convierte en el identificador único para el frijol,
frijol aliasing no es posible cuando se declara el grano de esta manera. Aquí es donde la configuración de Java viene al rescate. Vamos a considerar la
siguiente clase, que contiene una clase de configuración estática definida dentro de ella (sí, Primavera permite esto, y estamos siendo práctica aquí,
manteniendo toda la lógica en el mismo archivo):
com.apress.prospring5.ch3.config paquete;
com.apress.prospring5.ch3.annotated.Singer importación;
org.springframework.context.annotation.AnnotationConfigApplicationContext importación;
org.springframework.context.annotation.Bean importación; org.springframework.context.annotation.Configuration
importación; org.springframework.context.support.GenericApplicationContext importación;
org.springframework.context.support.GenericXmlApplicationContext importación;
java.util.Arrays de importación;
java.util.Map importación;
@Configuración
public static class {AliasBeanConfig
@Frijol
Cantante pública () {
101
Capítulo 3 ■ La introducción de la COI y Di en primavera
ctx.close (); }}
Esta clase contiene una definición de frijol para un bean de tipo Cantante declarado por la anotación de la cantante()
método con el @ Frijol anotación. Cuando no se proporciona ningún argumento a favor de esta anotación, el identificador único de la haba, su carné de identidad, se
convierte en el nombre del método. Por lo tanto, cuando se ejecuta la clase anterior, obtenemos el siguiente resultado:
alias cantante:
Identificación:
Para declarar alias, hacemos uso de la nombre atributo de la @ Frijol anotación. Este atributo es el uno por defecto para esta anotación,
lo que significa en este caso que se declara el grano por la anotación de la cantante()
método con @ Frijol, @Bean ( "cantante"), o @ Bean (name = "cantante") dará lugar al mismo resultado. El contenedor del resorte IoC creará un bean de tipo Cantante
y con la cantante CARNÉ DE IDENTIDAD.
Si el valor de este atributo es una cadena que contiene un separador-alias específico (espacio, coma, punto y coma), la cadena se convertirá en el ID del
grano. Sin embargo, si el valor porque es una matriz de cadenas, el primero se convierte en el carné de identidad y los otros se convierten en alias. Modificar la
configuración de frijol como se muestra aquí:
@Configuración
public static class {AliasBeanConfig
@Bean (nombre = { "John Mayer", "John", "Jonathan", "Johnny"}) Cantante
pública () {
volver nuevo Singer (); }}
102
Capítulo 3 ■ La introducción de la COI y Di en primavera
Cuando se trata de alias, en la primavera del 4,2 al @ AliasFor se introdujo anotación. Esta anotación se utiliza para declarar alias para los
atributos de anotación, y la mayoría de las anotaciones Spring hacer uso de ella. Por ejemplo, el @ Frijol anotación tiene dos atributos, nombre y valor, el
cual se declaran como alias para el uno al otro. El uso de esta anotación, que son alias explícitos. El siguiente fragmento de código es una
instantánea de la @ Frijol código de anotación y se toma desde el repositorio oficial de Primavera GitHub. El código y la documentación que no son
relevantes en el momento se han omitido: 4
org.springframework.context.annotation paquete;
java.lang.annotation.Documented importación;
java.lang.annotation.ElementType importación;
java.lang.annotation.Retention importación;
java.lang.annotation.RetentionPolicy importación;
java.lang.annotation.Target importación;
org.springframework.core.annotation.AliasFor importación;
...
@Target ({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @Retention
(RetentionPolicy.RUNTIME) @Documented
...
}
He aquí un ejemplo. Declarar una anotación llamada @ Premio que se puede utilizar en Cantante casos, por supuesto.
com.apress.prospring5.ch3.annotated paquete;
org.springframework.core.annotation.AliasFor importación;
103
Capítulo 3 ■ La introducción de la COI y Di en primavera
com.apress.prospring5.ch3.annotated paquete;
org.springframework.beans.factory.annotation.Qualifier importación;
org.springframework.stereotype.Component importación;
Cadena lírica privada = "Hemos encontrado un mensaje en una botella que estábamos bebiendo";
com.apress.prospring5.ch3.annotated paquete;
org.springframework.core.annotation.AliasFor importación;
@Premio
com.apress.prospring5.ch3.annotated paquete;
org.springframework.stereotype.Component importación;
Cadena lírica privada = "Hemos encontrado un mensaje en una botella que estábamos bebiendo";
104
Capítulo 3 ■ La introducción de la COI y Di en primavera
com.apress.prospring5.ch3.annotated paquete;
Cadena lírica privada = "Hemos encontrado un mensaje en una botella que estábamos bebiendo";
La creación de alias para los atributos de anotaciones usando otra anotación @ AliasFor tiene sus limitaciones. @ AliasFor no puede ser
utilizado en cualquier anotación estereotipo (@ Componente y sus especializaciones). la razón es que el manejo especial de estos valor atributos estaba
en su lugar años antes de @ AliasFor fue inventado. En consecuencia, debido a problemas de compatibilidad con versiones anteriores, simplemente no
con tales atributos de valor. Al escribir código para hacer tan (aliasing valor los atributos de anotaciones estereotipo), no hay errores de compilación se le
aparecen a usted, y el código, incluso podría funcionar, pero ningún argumento proporcionado por el alias serán ignorados. lo mismo vale para el
com.apress.prospring5.ch3 paquete;
estática {
instancia = new Singleton (); }
105
Capítulo 3 ■ La introducción de la COI y Di en primavera
Este patrón logra su objetivo de que le permite mantener y acceder a una sola instancia de una clase a través de su aplicación, pero lo hace a
expensas de un mayor acoplamiento. El código de aplicación siempre debe tener conocimiento explícito de la clase Singleton con el fin de obtener el
ejemplo- por completo la eliminación de la capacidad de codificar a las interfaces.
En realidad, el patrón Singleton es en realidad dos patrones en uno. La primera, y deseado, modelo implica el mantenimiento de una sola instancia de
un objeto. El segundo, y menos deseable, es un patrón para la búsqueda de objeto que elimina por completo la posibilidad de utilizar interfaces. Utilizando el
patrón Singleton también hace que sea difícil de extraerse implementaciones de manera arbitraria porque la mayoría de los objetos que requieren la instancia
Singleton Singleton acceder al objeto directamente. Esto puede causar todo tipo de dolores de cabeza cuando se está tratando a la unidad de probar la
aplicación, ya que son incapaces de sustituir el Singleton con una maqueta para realizar pruebas.
Afortunadamente, con la primavera se puede tomar ventaja del modelo de instancias singleton sin tener que trabajar todo el patrón de diseño Singleton.
Todos los frijoles en la primavera son, por defecto, creada como instancias Singleton, y la primavera se utilizan las mismas instancias para cumplir con todas las
peticiones de que Bean. Por supuesto, la primavera no se limita sólo a la utilización de la instancia Singleton; todavía puede crear una nueva instancia del grano
para satisfacer cada dependencia y cada llamada a getBean (). Se hace todo esto sin ningún impacto en el código de aplicación, y por esta razón, nos gustaría
hacer referencia a la primavera como el modo de ejemplificación agnóstico. Este es un concepto poderoso. Si usted comienza con un objeto que es un producto
único, pero luego descubre que no es muy adecuado para el acceso multi-hilo, se puede cambiar a un más de un elemento (prototipo) sin afectar a cualquiera de
su código de aplicación.
Aunque cambiar el modo de creación de instancias de bean no afectará su código de aplicación, sí causa algunos problemas si se basan en las
interfaces del ciclo de vida de la primavera. Cubrimos esto con más detalle en el capítulo 4 .
Cambiar el modo de ejemplificación de Singleton a más de un elemento es simple. Los siguientes fragmentos de configuración presentes cómo se
hace esto en XML y utilizando anotaciones:
\\ Singer.java
com.apress.prospring5.ch3.annotated paquete;
org.springframework.beans.factory.annotation.Value importación;
org.springframework.context.annotation.Scope importación;
org.springframework.stereotype.Component importación;
106