ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/appContext.xml");
Instantiating a container
Constructing application contexts from Resources
An application context constructor (for a specific application context type) generally takes a string or array of strings as the location path(s) of the resource(s) such as XML files that make up the definition of the context.
When such a location path doesn’t have a prefix, the specific Resource type built from
that path and used to load the bean definitions, depends on and is appropriate to the
specific application context. For example, if you create a
ClassPathXmlApplicationContext as follows:
The bean definitions will be loaded from the classpath, as a ClassPathResource will be
used. But if you create a FileSystemXmlApplicationContext as follows:
ApplicationContext ctx =
new FileSystemXmlApplicationContext("conf/appContext.xml");
The bean definition will be loaded from a filesystem location, in this case relative to the current working directory.
Note that the use of the special classpath prefix or a standard URL prefix on the
location path will override the default type of Resource created to load the
definition. So this FileSystemXmlApplicationContext…
ApplicationContext ctx =
new FileSystemXmlApplicationContext("classpath:conf/appContext.xml");
-
will actually load its bean definitions from the classpath. However, it is still a
FileSystemXmlApplicationContext. If it is subsequently used as aResourceLoader, any unprefixed paths will still be treated as filesystem paths.
Constructing ClassPathXmlApplicationContext instances - shortcuts
The ClassPathXmlApplicationContext exposes a number of constructors to enable
convenient instantiation. The basic idea is that one supplies merely a string array
containing just the filenames of the XML files themselves (without the leading path
information), and one also supplies a Class; the ClassPathXmlApplicationContext
will derive the path information from the supplied class.
An example will hopefully make this clear. Consider a directory layout that looks like this:
com/
foo/
services.xml
daos.xml
MessengerService.class
A ClassPathXmlApplicationContext instance composed of the beans defined in the
'services.xml' and 'daos.xml' could be instantiated like so…
ApplicationContext ctx = new ClassPathXmlApplicationContext(
new String[] {"services.xml", "daos.xml"}, MessengerService.class);
Please do consult the ClassPathXmlApplicationContext javadocs for details
on the various constructors.
Instantiating the Spring container using AnnotationConfigApplicationContext
The sections below document Spring’s AnnotationConfigApplicationContext, new 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.
Simple construction
In much the same way that Spring XML files are used as input when instantiating a
ClassPathXmlApplicationContext, @Configuration classes may be used as input when
instantiating an AnnotationConfigApplicationContext. This allows for completely
XML-free usage of the Spring container:
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
MyService myService = ctx.getBean(MyService.class);
myService.doStuff();
}
As mentioned above, 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. For example:
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(MyServiceImpl.class, Dependency1.class, Dependency2.class);
MyService myService = ctx.getBean(MyService.class);
myService.doStuff();
}
The above assumes that MyServiceImpl, Dependency1 and Dependency2 use Spring
dependency injection annotations such as @Autowired.
Building the container programmatically using register(Class<?>…)
An AnnotationConfigApplicationContext may be instantiated using a no-arg constructor
and then configured using the register() method. This approach is particularly useful
when programmatically building an AnnotationConfigApplicationContext.
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();
}
Enabling component scanning with scan(String…)
To enable component scanning, just annotate your @Configuration class as follows:
@Configuration
@ComponentScan(basePackages = "com.acme")
public class AppConfig {
...
}
|
Tip
|
Experienced Spring users will be familiar with the XML declaration equivalent from
Spring’s
|
In the example above, the com.acme package will be scanned, looking for any
@Component-annotated classes, and those classes will be registered as Spring bean
definitions within the container. AnnotationConfigApplicationContext exposes the
scan(String…) method to allow for the same component-scanning functionality:
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.scan("com.acme");
ctx.refresh();
MyService myService = ctx.getBean(MyService.class);
}
|
Note
|
Remember that |
Web Apps
Convenient ApplicationContext instantiation for web applications (web.xml)
You can create ApplicationContext instances declaratively by using, for example, a
ContextLoader. Of course you can also create ApplicationContext instances
programmatically by using one of the ApplicationContext implementations.
You can register an ApplicationContext using the ContextLoaderListener as follows:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/daoContext.xml /WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
The listener inspects the contextConfigLocation parameter. If the parameter does not
exist, the listener uses /WEB-INF/applicationContext.xml as a default. When the
parameter does exist, the listener separates the String by using predefined
delimiters (comma, semicolon and whitespace) and uses the values as locations where
application contexts will be searched. Ant-style path patterns are supported as well.
Examples are /WEB-INF/*Context.xml for all files with names ending with "Context.xml",
residing in the "WEB-INF" directory, and /WEB-INF/**/*Context.xml, for all such files
in any subdirectory of "WEB-INF".
Support for web applications with AnnotationConfigWebApplicationContext
A WebApplicationContext variant of AnnotationConfigApplicationContext is available
with AnnotationConfigWebApplicationContext. This implementation may be used when
configuring the Spring ContextLoaderListener servlet listener, Spring MVC
DispatcherServlet, etc. What follows is a web.xml snippet that 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>
Code-based Servlet 3.0+ container initialization
In a Servlet 3.0+ environment, you have the option of configuring the Servlet container
programmatically as an alternative or in combination with a web.xml file. Below is an
example of registering a DispatcherServlet:
import org.springframework.web.WebApplicationInitializer;
public class MyWebApplicationInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
XmlWebApplicationContext appContext = new XmlWebApplicationContext();
appContext.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
ServletRegistration.Dynamic registration = container.addServlet("dispatcher", new DispatcherServlet(appContext));
registration.setLoadOnStartup(1);
registration.addMapping("/");
}
}
WebApplicationInitializer is an interface provided by Spring MVC that ensures your
implementation is detected and automatically used to initialize any Servlet 3 container.
An abstract base class implementation of WebApplicationInitializer named
AbstractDispatcherServletInitializer makes it even easier to register the
DispatcherServlet by simply overriding methods to specify the servlet mapping and the
location of the DispatcherServlet configuration.
This is recommended for applications that use Java-based Spring configuration:
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { MyWebConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
If using XML-based Spring configuration, you should extend directly from
AbstractDispatcherServletInitializer:
public class MyWebAppInitializer extends AbstractDispatcherServletInitializer {
@Override
protected WebApplicationContext createRootApplicationContext() {
return null;
}
@Override
protected WebApplicationContext createServletApplicationContext() {
XmlWebApplicationContext cxt = new XmlWebApplicationContext();
cxt.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
return cxt;
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
AbstractDispatcherServletInitializer also provides a convenient way to add Filter
instances and have them automatically mapped to the DispatcherServlet:
public class MyWebAppInitializer extends AbstractDispatcherServletInitializer {
// ...
@Override
protected Filter[] getServletFilters() {
return new Filter[] { new HiddenHttpMethodFilter(), new CharacterEncodingFilter() };
}
}
Each filter is added with a default name based on its concrete type and automatically
mapped to the DispatcherServlet.
The isAsyncSupported protected method of AbstractDispatcherServletInitializer
provides a single place to enable async support on the DispatcherServlet and all
filters mapped to it. By default this flag is set to true.
Finally, if you need to further customize the DispatcherServlet itself, you can
override the createDispatcherServlet method.