转自:http://blog.csdn.net/zoutongyuan/article/details/41379851
基于Spring + Spring MVC + Mybatis 高性能web构建
一直想写这篇文章,前段时间 痴迷于JavaScript、NodeJs、AngularJs,做了大量的研究,对前后端交互有了更深层次的认识。
今天抽个时间写这篇文章,我有预感,这将是一篇很详细的文章,详细的配置,详细的注释,看起来应该很容易懂。
用最合适的技术去实现,并不断追求最佳实践。这就是架构之道。
希望这篇文章能给你们带来一些帮助,同时希望你们可以为这个项目贡献你的想法。
源码地址:https://github.com/starzou/quick4j 点击打开
看我们的项目结构:
是一个典型的Maven 项目 :
src/main/java:存放java源文件
src/main/resources:存放程序资源、配置文件
src/test/java:存放测试代码文件
src/main/webapp:web根目录
pom.xml : maven项目配置文件,管理依赖,编译,打包
主要的后端架构:Spring + Spring MVC + Mybatis + Apache Shiro
前端界面主要使用MetroNic 模板,
先看我们搭建完成,跑起来的效果,这样你才有兴趣看下去:
你可以 在github 上 checkout quick4j项目 查看 ,并跟下面步骤 来搭建:
强烈建议你,checkout https://github.com/starzou/quick4j ,在本地跑起来,再试着自己搭建框架
1、首先创建 maven 项目 ,用 idea 、eclipse 或 mvn 命令行都行
2、配置 pom.xml ,添加框架依赖
3、配置web.xml
web.xml是一个项目的核心,看看它的一些配置:
配置 ContextLoaderListener 监听器
配置Spring字符编码过滤器
配置shiro 安全过滤器
配置Spring MVC 核心控制器 DispatcherServlet
配置一些页面
spring 和 apache shiro 是由一个 ContextLoaderListener 监听器 加载的配置文件,并初始化
4、spring配置:
applicationContext.xml
application.properties
- ##JDBC Global Setting
- jdbc.driver=com.mysql.jdbc.Driver
- jdbc.url=jdbc:mysql://localhost:3306/quick4j?useUnicode=true&characterEncoding=utf-8
- jdbc.username=root
- jdbc.password=admin123
-
- ##DataSource Global Setting
-
- #配置初始化大小、最小、最大
- ds.initialSize=1
- ds.minIdle=1
- ds.maxActive=20
-
- #配置获取连接等待超时的时间
- ds.maxWait=60000
-
- #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
- ds.timeBetweenEvictionRunsMillis=60000
-
- #配置一个连接在池中最小生存的时间,单位是毫秒
- ds.minEvictableIdleTimeMillis=300000
ehcache.xml
- xml version="1.0" encoding="UTF-8"?>
- <ehcache updateCheck="false" name="txswx-ehcache">
- <diskStore path="java.io.tmpdir"/>
-
- <defaultCache maxEntriesLocalHeap="10000" eternal="true" timeToIdleSeconds="300" timeToLiveSeconds="600"
- overflowToDisk="true" maxEntriesLocalDisk="100000"/>
- ehcache>
5、
Apache Shiro 配置 : 要配置realms bean
- xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
-
- <description>apache shiro配置description>
-
- <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
- <property name="securityManager" ref="securityManager"/>
- <property name="loginUrl" value="/rest/page/login"/>
- <property name="successUrl" value="/rest/index"/>
- <property name="unauthorizedUrl" value="/rest/page/401"/>
- <property name="filterChainDefinitions">
- <value>
-
- /app/** = anon
- /assets/** = anon
-
- /rest/user/login = anon
-
- /** = authc
- value>
- property>
- bean>
-
-
- <bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
- <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml"/>
- bean>
-
-
- <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.MemorySessionDAO"/>
-
-
- <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
- <property name="sessionDAO" ref="sessionDAO"/>
- bean>
-
-
- <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
- <property name="realms">
- <list>
- <ref bean="securityRealm"/>
- list>
- property>
-
-
-
- bean>
-
-
- <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
-
- beans>
ehcache-shiro.xml
- <ehcache updateCheck="false" name="shiroCache">
-
- <defaultCache
- maxElementsInMemory="10000"
- eternal="false"
- timeToIdleSeconds="120"
- timeToLiveSeconds="120"
- overflowToDisk="false"
- diskPersistent="false"
- diskExpiryThreadIntervalSeconds="120"
- />
- ehcache>
6、MyBatis 配置
- xml version="1.0" encoding="UTF-8" ?>
-
- PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-config.dtd">
- <configuration>
- <properties>
- <property name="dialectClass" value="com.eliteams.quick4j.core.feature.orm.dialect.MySql5Dialect"/>
- properties>
-
-
- <settings>
-
-
- <setting name="cacheEnabled" value="true"/>
-
-
- <setting name="lazyLoadingEnabled" value="true"/>
-
-
- <setting name="multipleResultSetsEnabled" value="true"/>
-
-
- <setting name="useColumnLabel" value="true"/>
-
-
- <setting name="useGeneratedKeys" value="false"/>
-
-
- <setting name="autoMappingBehavior" value="PARTIAL"/>
-
-
-
-
-
-
-
-
- <setting name="safeRowBoundsEnabled" value="false"/>
-
-
- <setting name="mapUnderscoreToCamelCase" value="true"/>
-
-
- <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
-
-
- <setting name="aggressiveLazyLoading" value="false"/>
-
- settings>
-
- <typeAliases>
- <package name="com.eliteams.quick4j.web.model"/>
- <package name="com.eliteams.quick4j.web.enums"/>
- typeAliases>
-
- <plugins>
- <plugin interceptor="com.eliteams.quick4j.core.feature.orm.mybatis.PaginationResultSetHandlerInterceptor"/>
- <plugin interceptor="com.eliteams.quick4j.core.feature.orm.mybatis.PaginationStatementHandlerInterceptor"/>
- plugins>
-
- configuration>
7、
Spring MVC 配置
- xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:mvc="http://www.springframework.org/schema/mvc"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:p="http://www.springframework.org/schema/p"
- xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
- http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
-
-
- <context:component-scan base-package="com.eliteams.quick4j.web.controller"/>
-
-
-
- <mvc:annotation-driven validator="validator"/>
-
-
- <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
- <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
-
- <property name="validationMessageSource" ref="messageSource"/>
- bean>
-
-
- <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
- <property name="basenames">
- <list>
-
- <value>classpath:messagesvalue>
- <value>classpath:org/hibernate/validator/ValidationMessagesvalue>
- list>
- property>
- <property name="useCodeAsDefaultMessage" value="false"/>
- <property name="defaultEncoding" value="UTF-8"/>
- <property name="cacheSeconds" value="60"/>
- bean>
-
- <mvc:interceptors>
- <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
- mvc:interceptors>
-
- <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
- <property name="defaultLocale" value="zh_CN"/>
- bean>
-
-
- <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
- <property name="messageConverters">
- <list>
- <ref bean="mappingJacksonHttpMessageConverter"/>
- list>
- property>
- bean>
- <bean id="mappingJacksonHttpMessageConverter"
- class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
- <property name="supportedMediaTypes">
- <list>
- <value>text/plain;charset=UTF-8value>
- <value>application/json;charset=UTF-8value>
- list>
- property>
- bean>
-
-
-
- <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
- p:prefix="/WEB-INF/views/" p:suffix=".jsp"/>
-
-
- <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
- <property name="defaultEncoding" value="utf-8"/>
- <property name="maxUploadSize" value="10485760000"/>
- <property name="maxInMemorySize" value="40960"/>
- bean>
-
-
- <aop:config proxy-target-class="true">aop:config>
- <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
- <property name="securityManager" ref="securityManager"/>
- bean>
-
- beans>
messages.properties : hibernate-validator 配置文件,国际化资源文件
- #user
- user.username.null=用户名不能为空
- user.password.null=密码不能为空
log4j.properties :
- # DEBUG,INFO,WARN,ERROR,FATAL
- LOG_LEVEL=INFO
-
- log4j.rootLogger=${LOG_LEVEL},CONSOLE,FILE
-
- log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
- log4j.appender.CONSOLE.Encoding=utf-8
- log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
- #log4j.appender.CONSOLE.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss} %C{8}@(%F:%L):%m%n
- log4j.appender.CONSOLE.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss} %C{1}@(%F:%L):%m%n
-
- log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender
- log4j.appender.FILE.File=${catalina.base}/logs/quick4j.log
- log4j.appender.FILE.Encoding=utf-8
- log4j.appender.FILE.DatePattern='.'yyyy-MM-dd
- log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
- #log4j.appender.FILE.layout=org.apache.log4j.HTMLLayout
- log4j.appender.FILE.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH\:mm\:ss} %C{8}@(%F\:%L)\:%m%n
quick4j.sql
- /*
- SQLyog 企业版 - MySQL GUI v8.14
- MySQL - 5.5.27 : Database - quick4j
- *********************************************************************
- */
-
-
- /*!40101 SET NAMES utf8 */;
-
- /*!40101 SET SQL_MODE=''*/;
-
- /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
- /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
- /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
- /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
- CREATE DATABASE /*!32312 IF NOT EXISTS*/`quick4j` /*!40100 DEFAULT CHARACTER SET utf8 */;
-
- USE `quick4j`;
-
- /*Table structure for table `permission` */
-
- DROP TABLE IF EXISTS `permission`;
-
- CREATE TABLE `permission` (
- `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '权限id',
- `permission_name` varchar(32) DEFAULT NULL COMMENT '权限名',
- `permission_sign` varchar(128) DEFAULT NULL COMMENT '权限标识,程序中判断使用,如"user:create"',
- `description` varchar(256) DEFAULT NULL COMMENT '权限描述,UI界面显示使用',
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='权限表';
-
- /*Data for the table `permission` */
-
- insert into `permission`(`id`,`permission_name`,`permission_sign`,`description`) values (1,'用户新增','user:create',NULL);
-
- /*Table structure for table `role` */
-
- DROP TABLE IF EXISTS `role`;
-
- CREATE TABLE `role` (
- `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '角色id',
- `role_name` varchar(32) DEFAULT NULL COMMENT '角色名',
- `role_sign` varchar(128) DEFAULT NULL COMMENT '角色标识,程序中判断使用,如"admin"',
- `description` varchar(256) DEFAULT NULL COMMENT '角色描述,UI界面显示使用',
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='角色表';
-
- /*Data for the table `role` */
-
- insert into `role`(`id`,`role_name`,`role_sign`,`description`) values (1,'admin','admin','管理员');
-
- /*Table structure for table `role_permission` */
-
- DROP TABLE IF EXISTS `role_permission`;
-
- CREATE TABLE `role_permission` (
- `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '表id',
- `role_id` bigint(20) unsigned DEFAULT NULL COMMENT '角色id',
- `permission_id` bigint(20) unsigned DEFAULT NULL COMMENT '权限id',
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='角色与权限关联表';
-
- /*Data for the table `role_permission` */
-
- insert into `role_permission`(`id`,`role_id`,`permission_id`) values (1,2,1);
-
- /*Table structure for table `user` */
-
- DROP TABLE IF EXISTS `user`;
-
- CREATE TABLE `user` (
- `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户id',
- `username` varchar(50) DEFAULT NULL COMMENT '用户名',
- `password` char(64) DEFAULT NULL COMMENT '密码',
- `state` varchar(32) DEFAULT NULL COMMENT '状态',
- `create_time` datetime DEFAULT NULL COMMENT '创建时间',
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='用户表';
-
- /*Data for the table `user` */
-
- insert into `user`(`id`,`username`,`password`,`state`,`create_time`) values (1,'starzou','8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92',NULL,'2014-07-17 12:59:08');
-
- /*Table structure for table `user_role` */
-
- DROP TABLE IF EXISTS `user_role`;
-
- CREATE TABLE `user_role` (
- `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '表id',
- `user_id` bigint(20) unsigned DEFAULT NULL COMMENT '用户id',
- `role_id` bigint(20) unsigned DEFAULT NULL COMMENT '角色id',
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='用户与角色关联表';
-
- /*Data for the table `user_role` */
-