前言
传统的 XML 文件配置整合 SSM 框架是不是很繁琐? 如果框架搭建好了想移植到另外一个项目,又要在各种 XML 文件中许多参数, 缺少很快的配置移植性。
针对这些麻烦的问题,我做了一种 JavaConfig 自动整合方案,几乎不需要编写任何 XML 文件,包括 web.xml 文件。仅仅配置数据库的连接属性,三个框架就搭建完成了。
项目结构
Application.java 是核心配置类,所有的整合配置全部在里面。该类使用注解的方式配置了 Spring Bean ,使用 WebApplicationInitializer 接口配置了 web.xml 中的内容。
application.xml 是 Spring 的核心配置文件,主要只需要配置扫描的包即可
Application.java
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.XmlWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletRegistration;
/**
* SSMBoot Core Configuration Object 简化版
*
* Application.java 位置必须在项目最外层
* application.xml 配置文件名必须一致, 所有 Spring 的配置必须在该文件内
*
* @author haidnor
*/
public class Application {
static final String DRUID_URL = "jdbc:mysql://wangxiang.zone:33061/ssm";
static final String DRUID_USERNAME = "root";
static final String DRUID_PASSWORD = "root";
static final String DRUID_DRIVER_CLASS_NAME = "com.mysql.jdbc.Driver";
/* Default ------------------------------------------------------------------------------------------------------ */
static final String SPRING_MVC_VIEW_RESOLVER_PREFIX = "/";
static final String SPRING_MVC_VIEW_RESOLVER_SUFFIX = ".html";
static final String APPLICATION = Application.class.getPackage().getName();
static final String MAPPER_PACKAGE = APPLICATION;
static final String MYBATIS_TYPE_ALIASES_PACKAGE = APPLICATION;
static final String MYBATIS_MAPPER_LOCATIONS = "classpath*:" + APPLICATION.replace('.', '/') + "/**.xml";
/* WebApplicationInitializer ------------------------------------------------------------------------------------ */
static class WebContext implements WebApplicationInitializer {
ServletContext servletContext = null;
@Override
public void onStartup(ServletContext container) {
servletContext = container;
addDispatcherServlet();
addDruidStatViewServlet();
addCharacterEncodingFilter();
addContextLoaderListener();
addDruidWebStatFilter();
}
void addDispatcherServlet() {
XmlWebApplicationContext appContext = new XmlWebApplicationContext();
appContext.setConfigLocation("classpath:application.xml");
ServletRegistration.Dynamic dispatcherServlet =
servletContext.addServlet("DispatcherServlet", new DispatcherServlet(appContext));
dispatcherServlet.setLoadOnStartup(1);
dispatcherServlet.addMapping("/");
}
void addDruidStatViewServlet() {
StatViewServlet statViewServlet = new StatViewServlet();
ServletRegistration.Dynamic druidStatView =
servletContext.addServlet("DruidStatView", statViewServlet);
}
void addDruidWebStatFilter() {
WebStatFilter webStatFilter = new WebStatFilter();
webStatFilter.isExclusion("*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
FilterRegistration.Dynamic druidWebStatFilter =
servletContext.addFilter("DruidWebStatFilter", webStatFilter);
druidWebStatFilter.addMappingForUrlPatterns(null, false, "/*");
}
void addCharacterEncodingFilter() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
FilterRegistration.Dynamic encodingFilter =
servletContext.addFilter("characterEncodingFilter", characterEncodingFilter);
encodingFilter.addMappingForUrlPatterns(null, false, "/");
}
void addContextLoaderListener() {
servletContext.setInitParameter("contextConfigLocation", "classpath:application.xml");
servletContext.addListener(new ContextLoaderListener());
}
}
// Components ------------------------------------------------------------------------------------------------------
@Configuration
static class DataSource {
static final DruidDataSource DRUID_DATA_SOURCE = druidDataSource();
@Bean
MapperScannerConfigurer mapperScanner() {
MapperScannerConfigurer mapperScanner = new MapperScannerConfigurer();
mapperScanner.setBasePackage(MAPPER_PACKAGE);
mapperScanner.setSqlSessionFactoryBeanName("sqlSessionFactory");
return mapperScanner;
}
@Bean("sqlSessionFactory")
SqlSessionFactoryBean sqlSessionFactoryBean() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(DRUID_DATA_SOURCE);
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MYBATIS_MAPPER_LOCATIONS));
sqlSessionFactoryBean.setTypeAliasesPackage(MYBATIS_TYPE_ALIASES_PACKAGE);
return sqlSessionFactoryBean;
}
@Bean
DataSourceTransactionManager dataSourceTransactionManager() {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(DRUID_DATA_SOURCE);
return transactionManager;
}
@Bean
static DruidDataSource druidDataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(DRUID_DRIVER_CLASS_NAME);
dataSource.setUrl(DRUID_URL);
dataSource.setUsername(DRUID_USERNAME);
dataSource.setPassword(DRUID_PASSWORD);
return dataSource;
}
}
@Configuration
@EnableWebMvc
static class Web {
@Bean
ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix(SPRING_MVC_VIEW_RESOLVER_PREFIX);
viewResolver.setSuffix(SPRING_MVC_VIEW_RESOLVER_SUFFIX);
viewResolver.setExposeContextBeansAsAttributes(true);
return viewResolver;
}
}
}
application.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="cn.haidnor.project"/>
</beans>
maven
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.11</junit.version>
<commons-logging.version>1.2</commons-logging.version>
<log4j.version>1.2.17</log4j.version>
<org.springframework.version>5.0.8.RELEASE</org.springframework.version>
<aspectjweaver.version>1.8.13</aspectjweaver.version>
<aopalliance.version>1.0</aopalliance.version>
<mysql-connector-java.version>5.1.49</mysql-connector-java.version>
<druid.version>1.0.9</druid.version>
<mybatis.version>3.4.5</mybatis.version>
<mybatis-spring.version>1.3.1</mybatis-spring.version>
<javaee-api.version>7.0</javaee-api.version>
<jackson.version>2.9.5</jackson.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>${commons-logging.version}</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<type>jar</type>
<version>${javaee-api.version}</version>
<scope>compile</scope>
<optional>false</optional>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!--spring core start-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-indexer</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!--spring core end-->
<!--spring aop start-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!--spirng aop end-->
<!--spring aspects start-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!--spring aspects end-->
<!--spring instrumentation start -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!--spring instrumentation end-->
<!--spring messaging start -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!--spring messaging end-->
<!--spring data access start -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!--spring data access end-->
<!--spring web start -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!--spring web end -->
<!--spring test start -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!--spring test end -->
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector-java.version}</version>
</dependency>
<!-- MyBaits -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!-- MyBaits 与 Spring 的整合包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis-spring.version}</version>
</dependency>
<!-- Druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!--jackson依赖-->
<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>
</dependencies>
<build>
<finalName>SSMBoot</finalName>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<path>/</path>
<port>8080</port>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>