java - icon - Conversión del archivo XML de primavera a la clase @Configuration de primavera
jlabel netbeans (1)
Después de la pregunta Understanding Spring @Autowired usage , quería crear una base de conocimiento completa para la otra opción de cableado de primavera, la clase @Configuration
.
Supongamos que tengo un archivo XML de primavera que se ve así:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<import resource="another-application-context.xml"/>
<bean id="someBean" class="stack.overflow.spring.configuration.SomeClassImpl">
<constructor-arg value="${some.interesting.property}" />
</bean>
<bean id="anotherBean" class="stack.overflow.spring.configuration.AnotherClassImpl">
<constructor-arg ref="someBean"/>
<constructor-arg ref="beanFromSomewhereElse"/>
</bean>
</beans>
¿Cómo puedo usar @Configuration
en @Configuration
lugar? ¿Tiene algún efecto sobre el código en sí?
(Descargo de responsabilidad: esta respuesta se basa en la publicación de mi blog )
Migrando XML a @Configuration
Es posible migrar el xml a @Configuration
en unos pocos pasos:
Crear una clase anotada de
@Configuration
:@Configuration public class MyApplicationContext { }
Para cada etiqueta
<bean>
cree un método anotado con@Bean
:@Configuration public class MyApplicationContext { @Bean(name = "someBean") public SomeClass getSomeClass() { return new SomeClassImpl(someInterestingProperty); // We still need to inject someInterestingProperty } @Bean(name = "anotherBean") public AnotherClass getAnotherClass() { return new AnotherClassImpl(getSomeClass(), beanFromSomewhereElse); // We still need to inject beanFromSomewhereElse } }
Para importar
beanFromSomewhereElse
, necesitamos importar su definición. Se puede definir en un XML y usaremos@ImportResource
:@ImportResource("another-application-context.xml") @Configuration public class MyApplicationContext { ... }
Si el bean se define en otra clase
@Configuration
, podemos usar la anotación@Import
:@Import(OtherConfiguration.class) @Configuration public class MyApplicationContext { ... }
Después de importar otros XML o clases
@Configuration
, podemos usar los beans que declaran en nuestro contexto al declarar un miembro privado a la clase@Configuration
la siguiente manera:@Autowired @Qualifier(value = "beanFromSomewhereElse") private final StrangeBean beanFromSomewhereElse;
O utilícelo directamente como parámetro en el método que define el bean que depende de este
beanFromSomewhereElse
usando@Qualifier
siguiente manera:@Bean(name = "anotherBean") public AnotherClass getAnotherClass(@Qualifier (value = "beanFromSomewhereElse") final StrangeBean beanFromSomewhereElse) { return new AnotherClassImpl(getSomeClass(), beanFromSomewhereElse); }
La importación de propiedades es muy similar a la importación de bean desde otra clase xml o
@Configuration
. En lugar de usar@Qualifier
usaremos@Value
con propiedades de la siguiente manera:@Autowired @Value("${some.interesting.property}") private final String someInterestingProperty;
Esto también se puede usar con expresiones de SpEL .
Para permitir que la primavera trate tales clases como contenedores de frijoles, necesitamos marcar esto en nuestro xml principal colocando esta etiqueta en el contexto:
<context:annotation-config/>
Ahora puede importar clases
@Configuration
exactamente de la misma manera que crearía un bean simple:<bean class="some.package.MyApplicationContext"/>
Hay formas de evitar los XML de primavera por completo, pero no están en el alcance de esta respuesta. Puede encontrar una de estas opciones en mi publicación de blog en la que estoy basando mi respuesta.
Las ventajas y desventajas de usar este método
Básicamente encuentro que este método de declarar los frijoles es mucho más cómodo que usar XML debido a algunas ventajas que veo:
- Typos :
@Configuration
clases@Configuration
están compiladas y los errores tipográficos simplemente no permiten compilaciones - Fail fast (tiempo de compilación) : si olvida inyectar un bean, fallará en tiempo de compilación y no en tiempo de ejecución como ocurre con los XML
- Más fácil de navegar en IDE : entre constructores de beans para comprender el árbol de dependencias.
- Es posible depurar fácilmente el inicio de la configuración
Las desventajas no son muchas ya que las veo, pero hay algunas en las que podría pensar:
- Abuso : el código es más fácil de abusar que los XML
- Con XML, puede definir dependencias basadas en clases que no están disponibles durante el tiempo de compilación, pero que se proporcionan durante el tiempo de ejecución. Con
@Configuration
clases@Configuration
, debe tener las clases disponibles en el momento de la compilación. Por lo general, eso no es un problema, pero hay casos en que puede ser.
En pocas @Configuration
: está perfectamente bien combinar XML, @Configuration
y anotaciones en el contexto de su aplicación. A Spring no le importa el método con el que se declaró un frijol.