Instantiating The Spring Container By Using Annotationconfigapplicationcontext
Crear el contenedor de Spring con AnnotationConfigApplicationContext
Las secciones siguientes documentan AnnotationConfigApplicationContext de Spring, introducido en Spring 3.0. Esta implementación versátil de ApplicationContext admite como entrada no solo clases @Configuration, sino también clases @Component sencillas y clases anotadas con metadatos JSR-330.
Cuando se proporcionan clases @Configuration como entrada, la propia clase @Configuration se registra como una definición de bean y todos los métodos @Bean declarados en ella también se registran como definiciones de beans.
Cuando se proporcionan clases @Component y clases JSR-330, se registran como definiciones de beans y se presupone que, cuando sea necesario, utilizan metadatos de inyección de dependencias como @Autowired o @Inject.
Construcción simple
De manera similar a como los archivos XML de Spring se utilizan como entrada al crear un ClassPathXmlApplicationContext, puedes utilizar clases @Configuration como entrada al crear un AnnotationConfigApplicationContext.
Esto permite utilizar el contenedor de Spring por completo sin XML, como muestra el siguiente ejemplo:
public static void main(String[] args) {
ApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
MyService myService = ctx.getBean(MyService.class);
myService.doStuff();
}
Como se mencionó anteriormente, AnnotationConfigApplicationContext no se limita a trabajar únicamente con clases @Configuration. También puedes proporcionar al constructor cualquier clase @Component o clase anotada con JSR-330:
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(
MyServiceImpl.class, Dependency1.class, Dependency2.class);
MyService myService = ctx.getBean(MyService.class);
myService.doStuff();
}
El ejemplo anterior presupone que MyServiceImpl, Dependency1 y Dependency2 utilizan anotaciones de inyección de dependencias de Spring, como @Autowired.
Crear el contenedor mediante programación con register(Class<?>...)
Puedes crear un AnnotationConfigApplicationContext mediante un constructor sin argumentos y configurarlo después con el método register().
Este enfoque resulta especialmente útil cuando construyes un AnnotationConfigApplicationContext de forma programática:
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();
}
Activar la exploración de componentes con scan(String...)
Para activar la exploración de componentes, puedes anotar tu clase @Configuration de la siguiente manera:
@Configuration
@ComponentScan(basePackages = "com.acme") // (1)
public class AppConfig {
// ...
}
- Esta anotación activa la exploración de componentes.
Los usuarios con experiencia en Spring pueden reconocer la declaración XML equivalente del espacio de nombres context::
<beans>
<context:component-scan base-package="com.acme"/>
</beans>
En el ejemplo anterior, se explora el paquete com.acme para localizar clases anotadas con @Component, y esas clases se registran como definiciones de beans de Spring dentro del contenedor.
AnnotationConfigApplicationContext expone el método scan(String...) para proporcionar la misma funcionalidad de exploración de componentes:
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext();
ctx.scan("com.acme");
ctx.refresh();
MyService myService = ctx.getBean(MyService.class);
}
Recuerda que las clases @Configuration están meta-anotadas con @Component, por lo que son candidatas para la exploración de componentes.
En el ejemplo anterior, si AppConfig se declara en el paquete com.acme o en uno de sus subpaquetes, se detecta durante la llamada a scan(). Al ejecutar refresh(), todos sus métodos @Bean se procesan y se registran como definiciones de beans dentro del contenedor.
Compatibilidad con aplicaciones web mediante AnnotationConfigWebApplicationContext
Existe una variante de AnnotationConfigApplicationContext para WebApplicationContext: AnnotationConfigWebApplicationContext.
Puedes utilizar esta implementación al configurar el listener de servlet ContextLoaderListener de Spring, DispatcherServlet de Spring MVC y otros componentes similares.
El siguiente fragmento de web.xml configura una aplicación web típica de Spring MVC. Observa el uso de los parámetros contextClass tanto en el contexto raíz como en el servlet:
<web-app>
<!-- Configura ContextLoaderListener para usar AnnotationConfigWebApplicationContext
en lugar de XmlWebApplicationContext, que es el valor predeterminado. -->
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<!-- Las ubicaciones de configuración deben incluir una o varias clases
@Configuration completamente cualificadas, separadas por comas o espacios.
También se pueden especificar paquetes completamente cualificados
para explorar componentes. -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.acme.AppConfig</param-value>
</context-param>
<!-- Inicializa el contexto raíz de la aplicación como de costumbre
mediante ContextLoaderListener. -->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!-- Declara un DispatcherServlet de Spring MVC como de costumbre. -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<!-- Configura DispatcherServlet para usar AnnotationConfigWebApplicationContext
en lugar de XmlWebApplicationContext, que es el valor predeterminado. -->
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</init-param>
<!-- De nuevo, las ubicaciones de configuración deben incluir una o varias
clases @Configuration completamente cualificadas y separadas por
comas o espacios. -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.acme.web.MvcConfig</param-value>
</init-param>
</servlet>
<!-- Asigna todas las solicitudes de /app/* al servlet dispatcher. -->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
</web-app>
Para casos de uso programáticos, puedes utilizar GenericWebApplicationContext como alternativa a AnnotationConfigWebApplicationContext. Consulta el Javadoc de GenericWebApplicationContext para obtener más información.