spring注入bean有三种方式,通过注解,java Config 以及xml。而 注解优于java Config 而java Config优于xml。现在我们逐渐少用xml来配置springmvc项目了。本文将不用xml文件开启springMvc项目
1首先新建一个maven项目 pom.xml文件的内容如下所示(其中引用了常用的工具包日志包spring核心包以及springweb的包以及mybatis,等常用包)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zsq.cn</groupId>
<artifactId>spittr</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>spring Maven Webapp</name>
<url>http://maven.apache.org</url>
<!-- 项目属性 -->
<properties>
<!-- main version setting -->
<spring.version>4.1.9.RELEASE</spring.version>
<validator.version>5.2.4.Final</validator.version>
<mybatis.version>3.2.8</mybatis.version>
<mybatis-spring.version>1.2.3</mybatis-spring.version>
<druid.version>1.0.18</druid.version>
<ehcache.version>2.6.11</ehcache.version>
<ehcache-web.version>2.0.4</ehcache-web.version>
<shiro.version>1.2.3</shiro.version>
<!-- tools version setting -->
<slf4j.version>1.7.7</slf4j.version>
<commons-lang3.version>3.3.2</commons-lang3.version>
<commons-io.version>2.4</commons-io.version>
<commons-codec.version>1.9</commons-codec.version>
<commons-fileupload.version>1.3.1</commons-fileupload.version>
<commons-beanutils.version>1.9.1</commons-beanutils.version>
<jackson.version>2.2.3</jackson.version>
<fastjson.version>1.1.40</fastjson.version>
<xstream.version>1.4.7</xstream.version>
<guava.version>17.0</guava.version>
<dozer.version>5.5.1</dozer.version>
<poi.version>3.9</poi.version>
<freemarker.version>2.3.20</freemarker.version>
<!-- jdbc driver setting -->
<mysql.driver.version>5.1.30</mysql.driver.version>
<!-- environment setting -->
<jdk.version>1.6</jdk.version>
<tomcat.version>2.2</tomcat.version>
<webserver.port>8181</webserver.port>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- 依赖项定义 -->
<dependencies>
<!-- SPRING begin -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spring orm -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- bean validate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${validator.version}</version>
</dependency>
<!-- SPRING end -->
<!-- AOP begin -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.7.4</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.4</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
</dependency>
<!-- AOP end -->
<!-- PERSISTENCE begin -->
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis-spring.version}</version>
</dependency>
<!-- connection pool -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- jdbc driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.driver.version}</version>
<scope>runtime</scope>
</dependency>
<!-- PERSISTENCE end -->
<!-- WEB begin -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<!-- WEB end -->
<!-- LOGGING begin -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- common-logging 实际调用slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- java.util.logging 实际调用slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- LOGGING end -->
<!-- GENERAL UTILS begin -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons-codec.version}</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>${commons-beanutils.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- google java lib -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<!-- jackson json -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- freemarker engine -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>${freemarker.version}</version>
</dependency>
<!-- GENERAL UTILS end -->
<!-- TEST begin -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- TEST end -->
</dependencies>
</project>
2 新建一个SpittrWebAppInitializer 其中Spittr是项目的名字,这个类继承了AbstractAnnotationConfigDispatcherServletInitializer,容器会自动发现这个类,并用这个类来配置上下文,另外还可以在这个类中天剑filter(有两种方式)
/**
* <h3>该类继承了AbstractAnnotationConfigDispatcherServletInitializer,容器会自动发现这个类,并用这个类来配置上下文</h3>
* @author ZhaoSq
* @since 2017年9月21日 下午10:28:31
*/
public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{
@Override
protected Class<?>[] getRootConfigClasses() {//指定根配置类
return new Class<?>[] {RootConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {//指定web配置类
return new Class<?>[] {ServletConfig.class};
}
@Override
protected String[] getServletMappings() {//将DispatcherServlet映射到 "/" 即拦截所有请求交给DispatcherServlet处理
return new String[] {"/"};
}
/****************************下面两种添加过滤器的方法 二选一即可*****************************/
// @Override
// public Filter[] getServletFilters(){
// //编码过滤器
// CharacterEncodingFilter cef = new CharacterEncodingFilter();
// cef.setEncoding("UTF-8");
// cef.setForceEncoding(true);
//
// //登录过滤器
// LoginFilter lf = new LoginFilter();
// String[] unCheckUrls ={"/spittr/","/spittr/login"};
// lf.setUnCheckUrls(unCheckUrls);
//
// return new Filter[] {lf,cef};
//
// }
@Override
public void onStartup(ServletContext servletContext){
try {
super.onStartup(servletContext);
//登录过滤器
LoginFilter lf = new LoginFilter();
String[] unCheckUrls ={"/spittr/","/spittr/login"};
lf.setUnCheckUrls(unCheckUrls);
FilterRegistration.Dynamic lfilter = registerServletFilter(servletContext,lf);
lfilter.addMappingForServletNames(null, false, "/spittr/*");//最后一个参数是要过滤的url
CharacterEncodingFilter cef = new CharacterEncodingFilter();
cef.setEncoding("UTF-8");
cef.setForceEncoding(true);
FilterRegistration.Dynamic cefilter = registerServletFilter(servletContext, cef);
cefilter.addMappingForUrlPatterns(null, false, "/spittr/*");
} catch (ServletException e) {
e.printStackTrace();
}
}
/************************************添加过滤器结束****************************************/
}
3 上面的代码指定了两个java类,分别用来配置 应用程序的根配置和web配置
新建两个类 分别为 RootConfig 和ServletConfig(可以在这个类注入拦截器)
/**
* <h3>根配置</h3>
* @author ZhaoSq
* @since 2017年9月21日 下午10:33:27
*/
@Configuration
@ComponentScan(basePackages={"com.zsq.cn"},excludeFilters={
@Filter(type=FilterType.ANNOTATION,value=EnableWebMvc.class)
})
@ImportResource("/WEB-INF/classes/spring-context*.xml")//扫描xml里面注册的bean
@PropertySource(value={"/WEB-INF/classes/sys.properties"})//扫描属性文件,属性文件每个容器必须单独扫描,它们是不共享的
public class RootConfig {//上面的扫描策略是 扫面 com.zsq.cn 包下所有通过conponent、service等注解的bean. 但是不包括
//@EnableWebMvc修饰的(即在下面代码的ServletConfig类中扫描的注解,即在主容器中不扫描controller)bean.
/**
* 注册读取属性文件的控制器bean
* 扫描属性文件,属性文件每个容器必须单独扫描,它们是不共享的
* @return
*/
@Bean
public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
/**
* 国际化支持,jsp页面通过 <s:message code="spittr.wellcome" />
* 调用 resources文件夹下的validationMessage_zh_CN.properties文件的 spittr.wellcome对应的值
* 当然 这需要jsp页面 支持spring标签 jsp页面引入 <%@ taglib prefix="s" uri="http://www.springframework.org/tags"%>即可
* @return
*
*/
@Bean
public MessageSource messageSource(){
ResourceBundleMessageSource rbms = new ResourceBundleMessageSource();
rbms.setBasename("validationMessage_zh_CN");
return rbms;
}
}
/**
* <h3>web应用配置</h3>
* @author ZhaoSq
* @since 2017年9月21日 下午10:33:46
*/
@Configuration
@EnableWebMvc
@ComponentScan("com.zsq.cn.*.controller")//启用扫描组件,只扫描所有的controller包
@ImportResource("/WEB-INF/classes/spring-mvc.xml")
//扫描xml里面注册的bean,该容器会继承RootConfig.class配置的容器,即RootConfig.class里面扫描和注册的bean可以在此容器获取
@PropertySource(value={"/WEB-INF/classes/sys.properties"})
//扫描属性文件,属性文件每个容器必须单独扫描,它们是不共享的
public class ServletConfig extends WebMvcConfigurerAdapter {
/**
* 注册读取属性文件的控制器bean
* 扫描属性文件,属性文件每个容器必须单独扫描,它们是不共享的
* @return
*
*/
@Bean
public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
/**
* 国际化支持,jsp页面通过 <s:message code="spittr.wellcome" />
* 调用 resources文件夹下的validationMessage_zh_CN.properties文件的 spittr.wellcome对应的值
* 当然 这需要jsp页面 支持spring标签 jsp页面引入 <%@ taglib prefix="s" uri="http://www.springframework.org/tags"%>即可
* @return
*
*/
@Bean
public MessageSource messageSource(){
ResourceBundleMessageSource rbms = new ResourceBundleMessageSource();
rbms.setBasename("validationMessage_zh_CN");
return rbms;
}
/**
* 添加拦截器 也可以在上面扫描的spring-mvc.xml中通过xml添加
*
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new TestInterceptor()).addPathPatterns("/spittr/**")
.addPathPatterns("/*")
.addPathPatterns("/")
.excludePathPatterns("/spittr/login");
}
/**
* 配置jsp视图解析器
* @return 视图解析器
*
*/
@Bean
public ViewResolver viewResolver(){ //配置jsp视图解析器
InternalResourceViewResolver irvr = new InternalResourceViewResolver();
irvr.setPrefix("/WEB-INF/views/");
irvr.setSuffix(".jsp");
irvr.setExposeContextBeansAsAttributes(true);//使得可以在JSP页面中通过${ }访问容器中的bean
return irvr;
}
/**
* 配置静态资源的处理
*
*/
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){//配置静态资源的处理
configurer.enable();//通过此配置,DispatcherServlet将对静态资源请求转发到Servlet容器中默认的Servlet上,
//而不是DispatcherServlet来处理此请求。
}
}
4 这里给出上面类中用到的两个类 TestInterceptor.java 和 LoginFilter.java
注意在LoginFilter.java 有个需要注意的地方就是 当用户未登录的时候,也要进行页面跳转,代码中给出了两种不同视图技术对应的不同的跳转方式。
/**
* <h3>登录过滤器 对于未登录状态下通过URL的请求进行拦截</h3>
* @author ZhaoSq
* @since 2017年9月23日 下午7:34:23
*/
public class LoginFilter implements Filter{
/**
* 定义不拦截的请求路径,默认为空
*/
private String[] unCheckUrls = {};
public String[] getUnCheckUrls() {
return unCheckUrls;
}
public void setUnCheckUrls(String[] unCheckUrls) {
this.unCheckUrls = unCheckUrls;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request2 = (HttpServletRequest) request;
String uri = request2.getRequestURI(); //获取请求的路径
if(ArrayUtils.indexOf(unCheckUrls, uri)>-1){ //如果是不拦截的请求
chain.doFilter(request, response);
}else if(false){ //如果未登录 一般登录后在session里面放一个标识 通过判断标识来判断是否登录
// html 拦截跳转
// PrintWriter writer = response.getWriter();
// writer.write("<script>location.href=index.html</script>");
// jsp视图 拦截跳转
request.getRequestDispatcher("/").forward(request, response);
}else{
chain.doFilter(request, response);
}
}
@Override
public void destroy() {
}
}
/**
* <h3>测试拦截器,打印每个请求的耗时</h3>
* @author ZhaoSq
* @since 2017年9月23日 下午8:30:13
*/
public class TestInterceptor implements HandlerInterceptor {
/**
* 各个请求线程的开始时间
*/
private static final ThreadLocal<Long> startTimeThreadLocal = new ThreadLocal<Long>();
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
startTimeThreadLocal.set(System.currentTimeMillis());
System.out.println("---TestInterceptor拦截前---");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
if (modelAndView != null){
System.out.println("ViewName: " + modelAndView.getViewName());
}
System.out.println("---TestInterceptor拦截处理中---");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex)throws Exception {
System.out.println("---TestInterceptor拦截处理完成,共耗时:"
+(System.currentTimeMillis()-startTimeThreadLocal.get())+"毫秒---");
}
}
按照上面的步骤配置好后就可以启动项目了,按照平时的步骤编写conttoller 和service等服务。当然上面只是搭建了最基本的web服务,还没有配置datasource,以及事务管理等bean,这些你可以使用xml去配置也可以使用java Config来编写。