最近工作需要用到springmvc4,很久没用spring了变化还是很大,记录下搭建一个基于annotation的零配置文件的spring、springmvc、jpa、bootstrap的简单框架。
开发环境
- 开发工具:spring sts 3.6.4
- jdk:1.7.55 64 bit
- web server: Pivotal tc Server Developer Edition (Runtime) v3.1
- mysql: 5.5.23
- maven:3.2.3
springmvc annotation
@Configuration : 类似于spring配置文件,负责注册bean,对应的提供了@Bean注解。需要org.springframework.web.context.support.AnnotationConfigWebApplicationContext注册到容器中。
@ComponentScan : 注解类查找规则定义 <context:component-scan/>
@EnableAspectJAutoProxy : 激活Aspect自动代理 <aop:aspectj-autoproxy/>
@Import @ImportResource: 关联其它spring配置 <import resource="" />
@EnableCaching :启用缓存注解 <cache:annotation-driven/>
@EnableTransactionManagement : 启用注解式事务管理 <tx:annotation-driven />
@EnableWebMvcSecurity : 启用springSecurity安全验证
#servlet3.0
Servlet3.0规范,支持将web.xml相关配置也硬编码到代码中[servlet,filter,listener,等等],并由javax.servlet.ServletContainerInitializer的实现类负责在容器启动时进行加载, spring提供了一个实现类org.springframework.web.SpringServletContainerInitializer, 该类会调用所有org.springframework.web.WebApplicationInitializer的实现类的onStartup(ServletContext servletContext)方法,将相关的组件注册到服务器;
spring同时提供了一些WebApplicationInitializer的实现类供我们继承,以简化相关的配置,比如: org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer : 注册spring DispatcherServlet org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer : 注册springSecurity
同时,spring也提供了一些@Configuration的支持类供我们继承,以简化相关@Configuration的配置,比如: org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport : 封装了springmvc相关组件,我们可以通过注册新的@Bean和@Override相关方法,以实现对各个组件的注册; org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter : 封装类springsecurity相关组件
#WebConfig class
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.web.context.support.ServletContextAttributeExporter;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
import org.springframework.web.servlet.view.ResourceBundleViewResolver;
@Configuration
@EnableWebMvc
@ComponentScan(basePackages="com.xxx.controller")
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(new String[] { "/resources/**" }).addResourceLocations(new String[] { "/resources/" }).setCachePeriod(360000);
}
@Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Bean
public ServletContextAttributeExporter servletContextAttributeExporter(){
ServletContextAttributeExporter exporter =new ServletContextAttributeExporter();
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put("version", new SimpleDateFormat("yyMMddHHmmss").format(new Date()));
exporter.setAttributes(attributes);
return exporter;
}
@Bean
public MultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
// resolver.setMaxUploadSize(102400);
return resolver;
}
@Bean
public ViewResolver resourceBundleViewResolver(){
ResourceBundleViewResolver resolver = new ResourceBundleViewResolver();
resolver.setBasename("views");
resolver.setOrder(1);
return resolver;
}
@Bean
public ViewResolver interalResourceViewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setViewClass(JstlView.class);
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setOrder(2);
return resolver;
}
@Bean
public MessageSource messageSource(){
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasenames("classpath:messages/messages", "classpath:messages/validation");
// if true, the key of the message will be displayed if the key is not
// found, instead of throwing a NoSuchMessageException
messageSource.setUseCodeAsDefaultMessage(true);
messageSource.setDefaultEncoding("UTF-8");
// # -1 : never reload, 0 always reload
messageSource.setCacheSeconds(0);
return messageSource();
}
@Bean
public LocaleResolver localeResolver(){
CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
cookieLocaleResolver.setDefaultLocale(org.springframework.util.StringUtils.parseLocaleString("en"));
return cookieLocaleResolver;
}
}
#WebInitializer class
import java.util.EnumSet;
import java.util.Set;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.SessionTrackingMode;
import org.springframework.core.env.PropertyResolver;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.DispatcherServlet;
public class WebInitializer implements WebApplicationInitializer {
private PropertyResolver properties;
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.setSessionTrackingModes(EnumSet.of(SessionTrackingMode.COOKIE));
addRootContext(servletContext);
addWebContext(servletContext);
addFilters(servletContext);
}
private void addFilters(ServletContext servletContext) {
FilterRegistration.Dynamic springSecurityFilterChain = servletContext.addFilter("springSecurityFilterChain", new DelegatingFilterProxy());
springSecurityFilterChain.addMappingForUrlPatterns(null, false, "/*");
FilterRegistration.Dynamic httpMethodFilter = servletContext.addFilter("httpMethodFilter", new HiddenHttpMethodFilter());
httpMethodFilter.addMappingForUrlPatterns(null, false, "/*");
}
public void addRootContext(ServletContext servletContext){
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
String profile = properties.getProperty("spring.profile", "default");
rootContext.getEnvironment().setActiveProfiles(profile);
rootContext.refresh();
servletContext.addListener(new ContextLoaderListener(rootContext));
servletContext.setInitParameter("defaultHtmlEscape", "true");
}
public void addWebContext(ServletContext servletContext) {
AnnotationConfigWebApplicationContext mvcContext = new AnnotationConfigWebApplicationContext();
mvcContext.register(WebConfig.class);
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(mvcContext));
dispatcher.setLoadOnStartup(1);
Set<String> mappingConflicts = dispatcher.addMapping("/");
if (!mappingConflicts.isEmpty()) {
throw new IllegalStateException("'dispatcher' cannot be mapped to '/' under Tomcat versions <= 7.0.14");
}
}
}