声明:
本人提供这个 SpringMvc + Mybatis + Redis 的Demo 本着学习的态度,如果有欠缺和不足的地方,
给予指正,并且多多包涵
框架运行环境:
Maven版本:3.3.9
Eclipse版本:MARS.2
JDK版本:1.8
Tocat版本:8.0.36
框架结构:框架全采用maven管理 所以源码只有180KB左右要是不会Maven就请自行补习
annotation:自定义注解 实现的类似于shiro的权限 但是比较简单不喜勿喷 没shiro强大但是比他简单 然
后自己结合RBAC+Redis+ Intercept技术实现的 为什么没用shiro并不是shiro不强大只是不太喜欢那么
复杂的用法 虽然已经很简单了 我是懒得出奇的人 不过还是建议大家多去学习shiro这个权限框架毕竟连
spring都推荐使用Shiro RBAC是一个数据库的设计模型简单理解为:用户-角色-权限-资源 这里不再多
说有个网友帖子写得不错 点击打开链接 拦截器什么滴也不多说spring的核心之一
entity:实体类的父类很简单自己看源码就行
log4j:这里重写了log4j的SMTPAppender这个类 首先说说这个类是干嘛的 他是用来发送邮件的当报错
时邮件通知管理员,具体的请参考我的另一篇博客,上面有详细介绍点击打开链接
mapper:所有mapper的父类 默认提供了几个常用的方法
message:提示语相关的东西 都不知道咋描述 就是为了代码中不允许有一个中文和硬编码的存在 当然
自己也可以改改实现国际化
什么滴都没做只做了返回json这块 连异常都封装成JSon了
tools:看名字就知道一些常用的工具类 有什么身份证、经纬度、日期计算、DES和RSA加密、MD5之类
redis:这里重写了spring-data-redis里面的RedisCache、RedisCachemanager两个类和封装了一些其
他的包目的就是为了实现redis的自动续期和单用户登录功能(一个用户同时只能在一个地方登录)如果
需要实现不同平台的单用户登录需要自己小改一下 在缓存中多加个平台标识就行了
butler:这是web项目 名字不必纠结 介绍下包的作用
service:系统的一些服务类 这里只有定时任务和Spring mail邮件推送服务
system:这个看里面的包就知道干嘛用的了 就说说exception和interception这两个 一个是全局异常一
个是什么实体类校验权限等拦截器
框架的大致结构就介绍到这里 下面说一声配置的xml
web.xml
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>butlerdisplay-name>
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>
classpath*:applicationContext.xml,
classpath*:spring-*.xml
param-value>
context-param>
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListenerlistener-class>
listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
<filter>
<filter-name>CharacterEncodingfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
filter>
<filter-mapping>
<filter-name>CharacterEncodingfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<servlet>
<servlet-name>springservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath*:spring-mvc.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<filter>
<filter-name>HttpMethodFilterfilter-name>
<filter-class>org.springframework.web.filter.HttpPutFormContentFilterfilter-class>
filter>
<filter-mapping>
<filter-name>HttpMethodFilterfilter-name>
<servlet-name>springservlet-name>
filter-mapping>
<servlet-mapping>
<servlet-name>springservlet-name>
<url-pattern>/*url-pattern>
servlet-mapping>
web-app>
接下来是Spring的主配置文件applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:cache="http://www.springframework.org/schema/cache" xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-3.2.xsd">
<context:component-scan base-package="org.system,org.service.task" />
<bean id="propertyConfigurer" class="org.system.encrypt.DBConfigurer">
<property name="locations">
<list>
<value>classpath:conf.propertiesvalue>
list>
property>
bean>
<context:property-placeholder location="classpath:conf.properties" />
<bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="driverClassName" value="${db.driverClassName}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.user}" />
<property name="password" value="${db.password}" />
<property name="initialSize" value="${db.initialSize}" />
<property name="minIdle" value="${db.minIdle}" />
<property name="maxActive" value="${db.maxActive}" />
<property name="maxWait" value="${db.maxWait}" />
bean>
<bean name="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configuration" ref="configuration" />
<property name="plugins" ref="PaginationInterceptor" />
bean>
<bean id="configuration" class="org.apache.ibatis.session.Configuration">
<property name="callSettersOnNulls" value="true"/>
bean>
<bean name="PaginationInterceptor" class="org.system.intercept.PaginationInterceptor" />
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="org.system.mapper..*" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="insert*" propagation="REQUIRED" read-only="false" />
<tx:method name="delete*" propagation="REQUIRED" read-only="false" />
<tx:method name="update*" propagation="REQUIRED" read-only="false" />
<tx:method name="get*" propagation="SUPPORTS" />
tx:attributes>
tx:advice>
<aop:config proxy-target-class="true" expose-proxy="true">
<aop:pointcut id="transaction_pointcut" expression="execution(* org.system.service.impl..*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="transaction_pointcut" />
aop:config>
<bean id="exceptionHandler" class="org.system.exception.ExceptionResolver" />
<bean id="springContextUtil" class="org.service.utils.spring.SpringContextUtil" />
beans>
这里说一说有个数据库加密的东西在这里
<bean id="propertyConfigurer" class="org.system.encrypt.DBConfigurer">
<property name="locations">
<list>
<value>classpath:conf.propertiesvalue>
list>
property>
bean>
意思就是用DBConfigurer这个类来解密conf.properties这个文件内的几个配置 就是采用了des加密解
密主要为了防止配置文件泄露数据库的信息暴露 如果不用直接注释掉就可以使用明文了 稍后会把
properties相关文件贴出来
接下来是spring-mvc.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context" xmlns:task="http://www.springframework.org/schema/task"
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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd ">
<context:component-scan base-package="org.system.controller.impl" />
<mvc:resources location="/api/" mapping="/api/**" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/" />
<property name="suffix" value=".html" />
bean>
<bean id="validInterceptor" class="org.system.intercept.ValidInterceptor"/>
<aop:config>
<aop:pointcut id="validPoint" expression="execution(public * org.system.controller.impl..*.*(..))" />
<aop:advisor pointcut-ref="validPoint" advice-ref="validInterceptor" />
aop:config>
<task:scheduler id="scheduler" pool-size="10" />
<task:executor id="executor" pool-size="5-10" queue-capacity="200" rejection-policy="CALLER_RUNS" />
<task:annotation-driven executor="executor" scheduler="scheduler" />
<import resource="/org/system/config/*.xml" />
beans>
接下来是spring-mail.xml:这是用来配置Spring Mail发件人信息的 jdk8发布出去原因和解决方案请
点击
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${mail.smtp.host}" />
<property name="username" value="${mail.username}" />
<property name="password" value="${mail.password}" />
<property name="defaultEncoding" value="UTF-8">property>
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">${mail.smtp.auth}prop>
<prop key="mail.smtp.timeout">${mail.smtp.timeout}prop>
<prop key="mail.smtp.socketFactory.class">javax.net.ssl.SSLSocketFactoryprop>
props>
property>
bean>
beans>
接下来是spring-redis.xml:这是配置redis的东西
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-3.2.xsd">
<cache:annotation-driven cache-manager="cacheManager" />
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="minIdle" value="${redis.minIdle}" />
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="maxTotal" value="${redis.maxTotal}" />
<property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
bean>
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="poolConfig" ref="poolConfig" />
<property name="database" value="${redis.database}" />
<property name="port" value="${redis.port}" />
<property name="hostName" value="${redis.host}" />
<property name="password" value="${redis.password}" />
bean>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
bean>
<bean id="cacheManager" class="org.redis.cache.RedisCacheManager">
<constructor-arg name="redisOperations" ref="redisTemplate" />
<property name="transactionAware" value="true" />
<property name="expires">
<map>
<entry key="userCache" value="3600" />
<entry key="permissionCache" value="3600" />
map>
property>
bean>
beans>
接下来日志的xml也可以使用properties为毛我这里用xml具体原因请参考上文说的关于日志的文章
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss} [%p] [%c{3}] %m%n"/>
layout>
appender>
<appender name="info" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${catalina.home}/logs/${webapp.root}/infrastructure/info.log" />
<param name="Append" value="true" />
<param name="Threshold" value="INFO" />
<param name="datePattern" value="'.'yyyy-MM-dd" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss} [%p] [%c] %m%n" />
layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMax" value="INFO" />
<param name="LevelMin" value="INFO" />
filter>
appender>
<appender name="warn" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${catalina.home}/logs/${webapp.root}/infrastructure/warn.log" />
<param name="Append" value="true" />
<param name="Threshold" value="WARN" />
<param name="datePattern" value="'.'yyyy-MM-dd" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss} [%p] [%c] %m%n" />
layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMax" value="WARN" />
<param name="LevelMin" value="WARN" />
filter>
appender>
<appender name="error" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${catalina.home}/logs/${webapp.root}/infrastructure/error.log" />
<param name="Append" value="true" />
<param name="Threshold" value="ERROR" />
<param name="datePattern" value="'.'yyyy-MM-dd" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss} [%p] [%c] %m%n" />
layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMax" value="ERROR" />
<param name="LevelMin" value="ERROR" />
filter>
appender>
<appender name="email" class="org.main.log4j.SMTPAppender">
<param name="Threshold" value="ERROR" />
<param name="BufferSize" value="512" />
<param name="ErrorSize" value="5" />
<param name="From" value="****@****.com" />
<param name="SMTPHost" value="smtp.163.com" />
<param name="SMTPUsername" value="*****@****.com" />
<param name="SMTPPassword" value="***********" />
<param name="Subject" value="后台系统框架异常提醒,请尽快处理" />
<param name="To" value="******@qq.com" />
<param name="Bcc" value="*******@outlook.com"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss} [%p] [%c] %m%n" />
layout>
appender>
<appender name="asyncout" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="email" />
appender>
<logger name="org.springframework">
<level value="WARN" />
logger>
<logger name="org.system">
<level value="DEBUG" />
logger>
<root>
<level value="INFO" />
<appender-ref ref="console" />
<appender-ref ref="info" />
<appender-ref ref="warn" />
<appender-ref ref="error" />
<appender-ref ref="asyncout" />
root>
log4j:configuration>
最后一个butler.xml:权限部分注释了 想要测试放开取消注释即可
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc" 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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<mvc:annotation-driven validator="validator">
<mvc:message-converters register-defaults="true">
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json;charset=UTF-8" />
<property name="features">
<array>
<value>WriteMapNullValuevalue>
<value>WriteNullStringAsEmptyvalue>
array>
property>
bean>
mvc:message-converters>
mvc:annotation-driven>
<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:org/system/config/validvalue>
list>
property>
<property name="useCodeAsDefaultMessage" value="false" />
<property name="defaultEncoding" value="UTF-8" />
<property name="cacheSeconds" value="60" />
bean>
beans>
最后是conf.properties
这里加密的几个对应得明文分别是
url:jdbc:MySQL://localhsot:3306/butler?useUnicode=true&characterEncoding=utf8&mysqlEncoding=utf8
user:root
password:123456
如果对应的没变化就不需要改 后面提供的框架源码这块都会是错的请谅解
#数据库连接配置
db.driverClassName=com.mysql.jdbc.Driver
db.url=VjG9ty54tspjXih4i7GttGhMgOjH9n9fK+PmEKzqTNldvpAhYfSUuRBTf3b++nhyUZERvK3jb0VqFpnhJF0Whf1k7QSvjxxY1FaNlCT+Vz5cwk3kNBUfUHZ5EcLPNLOl
db.user=0q87vZtbVbk=
db.password=XfSWPx0Kqvg=
db.initialSize=2
db.minIdle=2
db.maxActive=10
db.maxWait=6000
#邮件服务器设置
mail.smtp.host=smtp.qiye.163.com
mail.smtp.port=465
mail.smtp.auth=true
mail.smtp.timeout=25000
mail.username=******@****.com
mail.password=*******
#Redis缓存配置
redis.minIdle=5
redis.maxIdle=100
redis.maxTotal=300
redis.maxWaitMillis=3000
redis.testOnBorrow=true
redis.host=127.0.0.1
redis.port=6379
redis.password=yxt123
redis.database=1
配置文件到这里都差不多了 文件内注解都有应该都能看懂至于框架的详细功能和实现方式就下次有时间在写!
最后如果还有不懂的地方 项目地址给奉献上了 源代码地址