|
This version is still in development and is not considered stable yet. For the latest stable version, please use Spring Framework 6.2.12! |
Instantiating the Spring Container by Using AnnotationConfigApplicationContext
The following sections document Spring’s AnnotationConfigApplicationContext, introduced in Spring
3.0. This versatile ApplicationContext implementation is capable of accepting not only
@Configuration classes as input but also plain @Component classes and classes
annotated with JSR-330 metadata.
When @Configuration classes are provided as input, the @Configuration class itself
is registered as a bean definition and all declared @Bean methods within the class
are also registered as bean definitions.
When @Component and JSR-330 classes are provided, they are registered as bean
definitions, and it is assumed that DI metadata such as @Autowired or @Inject are
used within those classes where necessary.
Simple Construction
In much the same way that Spring XML files are used as input when instantiating a
ClassPathXmlApplicationContext, you can use @Configuration classes as input when
instantiating an AnnotationConfigApplicationContext. This allows for completely
XML-free usage of the Spring container, as the following example shows:
-
Java
-
Kotlin
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()
}
As mentioned earlier, AnnotationConfigApplicationContext is not limited to working only
with @Configuration classes. Any @Component or JSR-330 annotated class may be supplied
as input to the constructor, as the following example shows:
-
Java
-
Kotlin
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()
}
The preceding example assumes that MyServiceImpl, Dependency1, and Dependency2 use Spring
dependency injection annotations such as @Autowired.
Building the Container Programmatically by Using register(Class<?>…)
You can instantiate an AnnotationConfigApplicationContext by using a no-arg constructor
and then configure it by using the register() method. This approach is particularly useful
when programmatically building an AnnotationConfigApplicationContext. The following
example shows how to do so:
-
Java
-
Kotlin
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()
}
Enabling Component Scanning with scan(String…)
To enable component scanning, you can annotate your @Configuration class as follows:
-
Java
-
Kotlin
@Configuration
@ComponentScan(basePackages = "com.acme") (1)
public class AppConfig {
// ...
}
| 1 | This annotation enables component scanning. |
@Configuration
@ComponentScan(basePackages = ["com.acme"]) (1)
class AppConfig {
// ...
}
| 1 | This annotation enables component scanning. |
|
Experienced Spring users may be familiar with the XML declaration equivalent from
Spring’s
|
In the preceding example, the com.acme package is scanned to look for any
@Component-annotated classes, and those classes are registered as Spring bean
definitions within the container. AnnotationConfigApplicationContext exposes the
scan(String…) method to allow for the same component-scanning functionality, as the
following example shows:
-
Java
-
Kotlin
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>()
}
Remember that @Configuration classes are
meta-annotated
with @Component, so they are candidates for component-scanning. In the preceding example,
assuming that AppConfig is declared within the com.acme package (or any package
underneath), it is picked up during the call to scan(). Upon refresh(), all its @Bean
methods are processed and registered as bean definitions within the container.
|
Support for Web Applications with AnnotationConfigWebApplicationContext
A WebApplicationContext variant of AnnotationConfigApplicationContext is available
with AnnotationConfigWebApplicationContext. You can use this implementation when
configuring the Spring ContextLoaderListener servlet listener, Spring MVC
DispatcherServlet, and so forth. The following web.xml snippet configures a typical
Spring MVC web application (note the use of the contextClass context-param and
init-param):
<web-app>
<!-- Configure ContextLoaderListener to use AnnotationConfigWebApplicationContext
instead of the default XmlWebApplicationContext -->
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<!-- Configuration locations must consist of one or more comma- or space-delimited
fully-qualified @Configuration classes. Fully-qualified packages may also be
specified for component-scanning -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.acme.AppConfig</param-value>
</context-param>
<!-- Bootstrap the root application context as usual using ContextLoaderListener -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Declare a Spring MVC DispatcherServlet as usual -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext
instead of the default XmlWebApplicationContext -->
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</init-param>
<!-- Again, config locations must consist of one or more comma- or space-delimited
and fully-qualified @Configuration classes -->
<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>
For programmatic use cases, a GenericWebApplicationContext can be used as an
alternative to AnnotationConfigWebApplicationContext. See the
GenericWebApplicationContext
javadoc for details.
|