Conceptos clave: @Bean y @Configuration
Los artefactos centrales en el nuevo soporte de configuración de Java de Spring son clases, marcadas con el @Configuration y los métodos marcados con la anotación @Bean.
La anotación @Bean se utiliza para indicar que El método crea una instancia, configura e inicializa un nuevo objeto que será administrado por el contenedor Spring IoC. Para aquellos familiarizados con la configuración XML <beans/> de Spring, la anotación @Bean juega el mismo papel que el elemento <bean/>. Puede utilizar métodos anotados @Bean con cualquier anotación @Component de Spring. Sin embargo, se usan con mayor frecuencia con beans anotados con @Configuration.
Anotar una clase con @Configuration indica que su propósito principal es ser un Definiciones de beans de origen. Además, las clases anotadas con @Configuration le permiten definir dependencias entre beans llamando a otros métodos @Bean en la misma clase. La clase más simple posible, anotada con @Configuration, se ve así:
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
@Configuration
class AppConfig {
@Bean
fun myService(): MyService {
return MyServiceImpl()
}
}
La clase anterior AppConfig es equivalente a la siguiente clase XML <beans/> from Spring:
<beans>
<bean id="myService" class="com.acme.services.MyServiceImpl"/>
</beans>
Las anotaciones @Bean y @Configuration se analizan en detalle en las siguientes secciones. Sin embargo, primero veremos las diferentes formas de crear un contenedor Spring usando una configuración basada en Java.
Creación de una instancia de un contenedor Spring usando AnnotationConfigApplicationContext
Lo siguiente Las secciones describen AnnotationConfigApplicationContext introducido en Spring 3.0. Esta implementación genérica de la interfaz ApplicationContext puede aceptar como entrada no solo clases anotadas con la anotación @Configuration, sino también clases regulares anotadas con la anotación @Component anotación, así como clases anotadas con metadatos de JSR-330.
Si las clases anotadas con la anotación @Configuration se especifican como entrada, la clase misma anotada con @Configuration se registra como una definición de bean y todos los métodos declarados en la clase que están marcados con la anotación @Bean también se registran como definiciones de bean.
Si se especifican clases marcadas con la anotación @Component, o de JSR-330, se registran como definiciones de beans y metadatos de inyección de dependencia como @Autowired o Se supone que @Inject se usa en estas clases cuando sea necesario.
Diseño simple
Así como los archivos Spring XML se usan como entrada al crear un ClassPathXmlApplicationContext, puede usar clases, anotadas con @Configuration, como entrada al crear AnnotationConfigApplicationContext. Esto le permite utilizar todo el contenedor Spring sin XML, como se muestra en el siguiente ejemplo:
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
MyService myService = ctx.getBean(MyService.class);
myService.doStuff();
}
import org.springframework.beans.factory.getBean
fun main() {
val ctx = AnnotationConfigApplicationContext(AppConfig::class.java)
val myService = ctx.getBean<MyService>()
myService.doStuff()
}
Como se mencionó anteriormente, AnnotationConfigApplicationContext no se limita a trabajar solo con clases anotadas con @Configuration. Cualquier clase anotada @Component o JSR-330 se puede proporcionar como entrada al constructor, como se muestra en el siguiente ejemplo:
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(MyServiceImpl.class, Dependency1.class, Dependency2.class);
MyService myService = ctx.getBean(MyService.class);
myService.doStuff();
}
import org.springframework.beans.factory.getBean
fun main() {
val ctx = AnnotationConfigApplicationContext(MyServiceImpl::class.java, Dependency1::class.java, Dependency2::class.java)
val myService = ctx.getBean<MyService>()
myService.doStuff()
}
El ejemplo anterior supone que MyServiceImpl, Dependency1 y Dependency2 usan anotaciones de inyección de dependencia de Spring como @Autowired.
Construyendo un contenedor mediante programación usando register(Class<?>…)
Puedes crear AnnotationConfigApplicationContext usando un constructor sin argumentos y luego configurándolo usando el método register(). Este enfoque es especialmente útil al construir AnnotationConfigApplicationContext mediante programación. El siguiente ejemplo muestra cómo hacer esto:
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class, OtherConfig.class);
ctx.register(AdditionalConfig.class);
ctx.refresh();
MyService myService = ctx.getBean(MyService.class);
myService.doStuff();
}
import org.springframework.beans.factory.getBean
fun main() {
val ctx = AnnotationConfigApplicationContext()
ctx.register(AppConfig::class.java, OtherConfig::class.java)
ctx.register(AdditionalConfig::class.java)
ctx.refresh()
val myService = ctx.getBean<MyService>()
myService.doStuff()
}
Habilite el escaneo de componentes usando scan(String...)
Para habilitar escaneando componentes, puede anotar su clase con @Configuration de esta manera:
@Configuration
@ComponentScan(basePackages = "com.acme")
public class AppConfig {
// ...
}
- Esta anotación le permite escanear componentes.
@Configuration
@ComponentScan(basePackages = ["com.acme"])
class AppConfig {
// ...
}
- Esta anotación permite escanear componentes.
Los usuarios experimentados de Spring pueden estar familiarizados con el equivalente Spring de la declaración XML del espacio de nombres context:, que se muestra en el siguiente ejemplo:
<beans>
<context:component-scan base-package="com.acme"/>
</beans>
En el ejemplo anterior, el paquete com.acme se analiza en busca de clases. anotadas con @Component, y estas clases se registran como definiciones de Spring Bean en el contenedor. AnnotationConfigApplicationContext expone el método scan(String...) para proporcionar la misma funcionalidad de escaneo de componentes como se muestra en el siguiente ejemplo:
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.scan("com.acme");
ctx.refresh();
MyService myService = ctx.getBean(MyService.class);
}
fun main() {
val ctx = AnnotationConfigApplicationContext()
ctx.scan("com.acme")
ctx.refresh()
val myService = ctx.getBean<MyService>()
}
@Configuration están metaanotadas con
@Component y, por lo tanto, son candidatas para el escaneo de componentes. En el ejemplo anterior, asumiendo que
AppConfig está declarado en el paquete
com.acme (o cualquier otro paquete debajo de él), se intercepta durante la llamada a
scan(). Después de
refresh(), todos sus métodos anotados con
@Bean se procesan y registran como definiciones de beans en el contenedor.
Soporte de aplicaciones web con AnnotationConfigWebApplicationContext
Se puede acceder a la variante WebApplicationContext de la clase AnnotationConfigApplicationContext mediante AnnotationConfigWebApplicationContext. Puede utilizar esta implementación al configurar un escucha de servlet ContextLoaderListener de Spring, DispatcherServlet de Spring MVC, etc. El siguiente fragmento web.xml configura una aplicación web típica en Spring MVC (tenga en cuenta el uso de los parámetros de contexto y de inicio contextClass):
<web-app>
<!-- Configuring ContextLoaderListener to use AnnotationConfigWebApplicationContext
instead of the standard XmlWebApplicationContext -->
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<!-- The configuration location must consist of one or more comma- or space-separated
fully qualified class names annotated with @Configuration. Full package names can also be -->
<context-param>
<param-name>contextConfigLocation>/param-name>
<param-value>com.acme.AppConfig</param-value>
</context-param>
<!-- We bootstrap the root application context as usual, using ContextLoaderListener -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-classм
</listener>
<!-- Declare the DispatcherServlet in Spring MVC as usual -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- Configure the DispatcherServlet to use AnnotationConfigWebApplicationContext
instead of the standard XmlWebApplicationContext -->
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</init-param>
<!-- Again, configuration locations must consist of one or more comma- or space-separated
and fully qualified class names annotated with @Configuration -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.acme.web.MvcConfig</param-value>
</init-param>
</servlet>
<!-- map all requests for /app/* to the dispatcher servlet -->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
</web-app>
GenericWebApplicationContext se puede utilizar como alternativa a
AnnotationConfigWebApplicationContext. Para obtener más información, consulte el javadoc en
GenericWebApplicationContext.
GO TO FULL VERSION