您的位置:首页 > 编程语言 > Java开发

Spring @MVC configuration without XML

2015-06-06 00:00 381 查看
XML is no longer hip. Actually, there is nothing as unhip as last year’s hip. That is until it becomes hip again 30 years later in failed irony.

Honestly, if you’ve been programming Java EE since the 90s, you know full well how error prone XML config files can be. A glance at an EJB XML config file – especially the CMP relationship config from version 2 – would make any sane person run screaming into
the night. Tools were supposed to help, but they really didn’t.

Even the Spring Framework, a music major’s wildly successful solution to Java EE’s problems, has been inundated by XML config files. Until now.

Let’s see how we can configure a Spring @MVC web app with no XML.


Java EE update

Starting with the Servlet 3.0 specification, we can do away with the venerable WEB-INF/web.xml configuration file. In order to do this you must do the following:

Write a class that implements
javax.servlet.ServletContainerInitializer


Create a file named META-INF/services/javax.servlet.ServletContainerInitializer which contains the fully qualified name of your implementation.


Spring

Beginning with release 3.1, Spring provides an implementation of the ServletContainerInitializer interface aptly named SpringServletContainerInitializer.
Take a peek inside spring-web-[version 3.1 and above].jar and you’ll see the META-INF/services file mentioned above.

The SpringServletContainerInitializer class delegates to an implementation of

org.springframework.web.WebApplicationInitializer that
you provide. There is just one method that you need to implement: WebApplicationInitializer#onStartup(ServletContext). You are handed the ServletContext that you need to initialize.

12345678910111213public class WebAppInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) { WebApplicationContext appContext = set up the context ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(appContext)); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/"); } }

Setting up the app contexts

Since we are avoiding writing XML config files, I suggest that instead of using the XmlWebApplicationContext class, use the AnnotationConfigWebApplicationContext which supports classpath scanning for Spring annotation based configuration. You can explicitly add configuration classes, or have the context scan for them.To start up and shut down the context, we add a ContextLoaderListener.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

@Override

public
void
onStartup(ServletContext
servletContext)
throws
ServletException
{

//
Create the root appcontext

AnnotationConfigWebApplicationContext
rootContext
=
new
AnnotationConfigWebApplicationContext();

rootContext.register(RootConfig.class);

//
since we registered RootConfig instead of passing it to the constructor

rootContext.refresh();

//
Manage the lifecycle of the root appcontext

servletContext.addListener(new
ContextLoaderListener(rootContext));

servletContext.setInitParameter("defaultHtmlEscape",
"true");

//
now the config for the Dispatcher servlet

AnnotationConfigWebApplicationContext
mvcContext
=
new
AnnotationConfigWebApplicationContext();

mvcContext.register(WebMvcConfig.class);

//
The main Spring MVC servlet.

ServletRegistration.Dynamic
appServlet
=
servletContext.addServlet(

"appServlet",
new
DispatcherServlet(mvcContext));

appServlet.setLoadOnStartup(1);

Set<String>
mappingConflicts
=
appServlet.addMapping("/");

if
(!mappingConflicts.isEmpty())
{

for
(String
s
:
mappingConflicts)
{

logger.error("Mapping
conflict: "
+
s);

}

throw
new
IllegalStateException(

"'appServlet'
cannot be mapped to '/' under Tomcat versions <= 7.0.14");

}

}


Java config files

The RootConfig Java class we specified in the previous example needs to use the @Configuration annotation. Essentially this class corresponds to the <beans> element in Spring XML config files. The <bean> elements are now methods with the @Bean annotation that
return a bean instance. The <context:component-scan> element is now the class level annotation @ComponentScan.

12345678910@Configuration@ComponentScan(basePackages = { "com.rockhoppertech.mvc.service", "com.rockhoppertech.mvc.repositories.internal" })public class RootConfig { @Bean public SomeClass someClass() { return someInstance; } }

Filters

You can also create any Servlet Filters here. Here are a few Spring provided Filters.In this example I set up the CharacterEncodingFilter.

1

2

3

4

5

6

7

8

9

10

11

12

13

@Override

public
void
onStartup(ServletContext
servletContext)
throws
ServletException
{

...

FilterRegistration.Dynamic
fr
=
servletContext.addFilter("encodingFilter",

new
CharacterEncodingFilter());

fr.setInitParameter("encoding",
"UTF-8");

fr.setInitParameter("forceEncoding",
"true");

fr.addMappingForUrlPatterns(null,
true,
"/*");

...

}


@Enable*

XML namespaces are replaced by class level annotations that begin with @Enable.

@EnableWebMvc

@EnableAsync

@EnableScheduling

@EnableLoadTimeWeaving

@EnableTransactionManagement

Right now we configure MVC using the mvc: XML namespace, for example: <mvc:annotation:driven/>. The @EnableWebMvc annotation is the replacement.


Spring MVC configuration

Write a configuration class that contains the @EnableWebMvc annotation, which is defined byDelegatingWebMvcConfiguration.
In addition, you will probably do a component scan for controllers here.

To customize the defaults, implement WebMvcConfigurer or
extend WebMvcConfigurerAdapter.
Any overridden method that does not return NULL will use that value instead of the default.

1

2

3

4

5

6

7

8

@Configuration

@EnableWebMvc

//
scan for controllers

@ComponentScan(basePackages
=
{
"com.rockhoppertech.mvc.web"
})

public
class
WebMvcConfig
extends
WebMvcConfigurerAdapter
{

@Bean
ViewResolver
viewResolver()
{
...
}

@Bean
MessageSource
messageSource()
{
...
}

etc.


Resources

Github project

Spring MVC

Spring
MVC config

Spring
Java-based container configuration

Tomcat 7 mapping bug

Servlet 3.0 Specification

Beams’ 3.1 presentation
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: