使用aop切面编程进行日志记录并入库
上代码:
系统日志service,dao,mapper,bean
package com.tzc.webapi.service.interfece;
import com.github.pagehelper.PageInfo;
import com.tzc.webapi.bean.SysUserLog;
import com.tzc.webapi.bean.SysUserLogQuery;
public interface SysUserLogServiceImp {
/**
* 添加系统用户日志
*
* @param sysUserLog 日志信息
*/
void addUserLog(SysUserLog sysUserLog);
/**
* 分页获取日志列表
*
* @param query 查询参数
* @param start 页数
* @param length 每页个数
* @return
*/
PageInfo queryPage(SysUserLogQuery query, Integer start, Integer length) throws Exception;
}
package com.tzc.webapi.service;
import com.github.pagehelper.PageInfo;
import com.tzc.webapi.bean.SysUserLog;
import com.tzc.webapi.bean.SysUserLogQuery;
import com.tzc.webapi.dao.masterBook.SysUserLogMapper;
import com.tzc.webapi.service.interfece.SysUserLogServiceImp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
public class SysUserLogService implements SysUserLogServiceImp {
@Autowired
private SysUserLogMapper userLogMapper;
// @Autowired
// private SysDbServiceImp dbService;
/**
* sys_user_log
*/
private static String preTableName = "sys_user_log";
// public void addUserLogTable(SysUserLog sysUserLog) {
// try {
// userLogMapper.insertToTable(getUserLogTableName(), sysUserLog);
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
@Override
public void addUserLog(SysUserLog sysUserLog) {
try {
userLogMapper.insert(sysUserLog);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public PageInfo queryPage(SysUserLogQuery query, Integer start, Integer length) throws Exception {
return null;
}
}
// public PageInfo queryPage(SysUserLogQuery query, Integer start, Integer length) throws Exception {
// // 判断开始结束日期是否为空
// if (query.getStartTime() == null || query.getEndTime() == null) {
// throw new RuntimeException("开始、结束时间不能为空");
// }
//
// // 查询日志表表名
// List userLogTableName = null;
//
// if (userLogTableName == null) {
// userLogTableName = dbService.queryUserLogTableName();
// }
// String logTable = "";
// if (userLogTableName == null ? true : userLogTableName.size() > 0) {
// // 标记是否比较开始时间
// Boolean isStart = true;
// for (int i = 0; i < userLogTableName.size(); i++) {
// if (isStart) {
// // 如果表创建时间与开始时间时间同年同月 则使循环体往下执行
// if (DateUtil.equals(changeToDate(userLogTableName.get(i)), query.getStartTime())
// || DateUtil.countSecond(changeToDate(userLogTableName.get(i)), query.getStartTime()) >= 0) {
// logTable = " ( select * from " + preTableName;
// isStart = false;
// } else {
// continue;
// }
// }
// logTable = logTable + " union all " + " select * from " + userLogTableName.get(i);
// // 如果表创建时间与结束时间同年同月 则跳出循环
// if (DateUtil.equals(changeToDate(userLogTableName.get(i)), query.getEndTime())) {
// break;
// }
// }
// if (!isStart) {
// logTable = logTable + " ) ";
// } else {
// logTable = preTableName;
// }
// } else {
// logTable = preTableName;
// }
// // 分页计算
// start = start / length + 1;
// PageHelper.startPage(start, length);
// // List userLogs = userLogMapper.selectAll(query);
// List userLogs = userLogMapper.selectAllByTables(logTable, query);
// PageInfo pageInfo = new PageInfo(userLogs);
// return pageInfo;
// }
//
// /**
// * 获取最新的日志表表名
// *
// * @return
// */
// private String getUserLogTableName() {
// //取用户日志表名集合
// List userLogTableName = null;
// // 判断最新表名是否与该月同月,不同月则创建该月日志表
// if (userLogTableName == null ? true : userLogTableName.size() <= 0) {
// dbService.createTable("sys_user_log", true);
// } else {
// // userLogTableName.size() > 0
// String tableName = userLogTableName.get(userLogTableName.size() - 1);
// if (!DateUtil.equals(changeToDate(tableName), new Date(System.currentTimeMillis()))) {
// // 不同月,则创建该月表,并更新日志缓存
// dbService.createTable("sys_user_log", true);
// }
// }
// if (userLogTableName == null ? true : userLogTableName.size() <= 0) {
// return preTableName;
// }
//
// return userLogTableName.get(userLogTableName.size() - 1);
// }
//
// /**
// * 获取名称后缀
// * 格式: 20170301
// *
// * @return
// */
// @SuppressWarnings("unused")
// private String getSufName() {
// Date d = new Date();
// String s = DateUtil.date2String(d, false);
// s = s.replace("-", "");
// s = s.substring(0, s.length() - 2);
// s = s + "01";
// return s;
// }
//
// /**
// * 计算日志表时间
// *
// * @param tabelName 表名
// * @return
// */
// private Date changeToDate(String tabelName) {
// int lastIndexOf = tabelName.lastIndexOf('_');
// if (lastIndexOf >= 0) {
// tabelName = tabelName.substring(lastIndexOf + 1);
// String strDate = tabelName.substring(0, 4) + "-" + tabelName.substring(4, 6) + "-"
// + tabelName.substring(6, 8);
// return DateUtil.string2Date(strDate);
// } else {
// return null;
// }
// }
//
//}
package com.tzc.webapi.dao.masterBook;
import com.tzc.webapi.bean.SysUserLog;
import com.tzc.webapi.bean.SysUserLogQuery;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface SysUserLogMapper {
/**
* 新增日志记录
* @param sysUserLog
* @return
*/
int insert(SysUserLog sysUserLog);
/**
* 添加日志到指定数据库
* @param tableName
* @param sysUserLog
* @return
*/
int insertToTable(@Param("tableName") String tableName, @Param("log") SysUserLog sysUserLog);
/**
* 查询所有
* @return
*/
List selectAll(SysUserLogQuery query);
/**
* 查询指定条件的数据表
* @param table
* @param query
* @return
*/
List selectAllByTables(@Param("table") String table,@Param("query") SysUserLogQuery query);
}
log_id, user_id, module_name, operate, time, class_name, method_name, params, ip
insert into ${tableName}
(log_id, user_id, module_name, operate, time, class_name, method_name, params, ip)
values
(
#{log.logId,jdbcType=VARCHAR},
#{log.userId,jdbcType=VARCHAR},
#{log.moduleName,jdbcType=VARCHAR},
#{log.operate,jdbcType=VARCHAR},
#{log.time,jdbcType=TIMESTAMP},
#{log.className,jdbcType=VARCHAR},
#{log.methodName,jdbcType=VARCHAR},
#{log.params,jdbcType=VARCHAR},
#{log.ip,jdbcType=VARCHAR}
)
insert into sys_user_log
(log_id, user_id, module_name, operate, time, class_name, method_name, params, ip)
values
(
#{logId,jdbcType=VARCHAR},
#{userId,jdbcType=VARCHAR},
#{moduleName,jdbcType=VARCHAR},
#{operate,jdbcType=VARCHAR},
#{time,jdbcType=TIMESTAMP},
#{className,jdbcType=VARCHAR},
#{methodName,jdbcType=VARCHAR},
#{params,jdbcType=VARCHAR},
#{ip,jdbcType=VARCHAR}
)
package com.tzc.webapi.bean;
import java.io.Serializable;
import java.util.Date;
/**
* 系统用户日志
* @auther jarome
* @date 2017/11/29
**/
public class SysUserLog implements Serializable {
private static final long serialVersionUID = 1L;
/**日志id*/
private String logId;
/**用户id*/
private String userId;
/**模块名称*/
private String moduleName;
/**操作*/
private String operate;
/**时间*/
private Date time;
/**类名*/
private String className;
/**方法名*/
private String methodName;
/**传入参数*/
private String params;
/**操作ip*/
private String ip;
public static long getSerialVersionUID() {
return serialVersionUID;
}
public String getLogId() {
return logId;
}
public void setLogId(String logId) {
this.logId = logId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getModuleName() {
return moduleName;
}
public void setModuleName(String moduleName) {
this.moduleName = moduleName;
}
public String getOperate() {
return operate;
}
public void setOperate(String operate) {
this.operate = operate;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public String getParams() {
return params;
}
public void setParams(String params) {
this.params = params;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
}
自定义注解:
package com.tzc.webapi.anon;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @auther
* @date
**/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface LogAnnotation {
/**
* 模块名称
*/
String moduleName() default "";
/**
* 操作内容
*/
String operate() default "";
}
package com.tzc.webapi.interceptor;
import com.tzc.webapi.anon.LogAnnotation;
import com.tzc.webapi.bean.SysUserLog;
import com.tzc.webapi.service.SysUserLogService;
import com.tzc.webapi.util.IdUtil;
import com.tzc.webapi.util.IpUtil;
import com.tzc.webapi.util.JsonUtil;
import com.tzc.webapi.util.SpringUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
/**
* 日志拦截器
*
*/
//
@Component
@Aspect
public class LogInterceptor {
/**
* execution(* com.tzc.webapi.service.*.*(..))||
* 方法正常完成后执行方法
* @param
*/
@Pointcut("@annotation(com.tzc.webapi.anon.LogAnnotation)")
public void pointCut() {}
@After("pointCut()")
public void afterReturning(JoinPoint point) {
try {
//取当前用户
String userId = "teste123";
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
SysUserLog userLog = new SysUserLog();
String targetName = point.getTarget().getClass().getName();
Class targetClass = Class.forName(targetName);
String methodName = point.getSignature().getName();
Method[] method = targetClass.getMethods();
Object[] params = point.getArgs(); // 获得参数列表
for (Method m : method) {
if (m.getName().equals(methodName)) {
Class[] tmpCs = m.getParameterTypes();
if (tmpCs.length == params.length) {
// 获取注解内容
LogAnnotation logAnnotation = m.getAnnotation(LogAnnotation.class);
if(logAnnotation != null){
//写入参数
if(params.length>0){
// 使用json转换工具 将参数转为json串,以便存入数据库
String jsonStr = JsonUtil.toJSONStr(params);
userLog.setParams(jsonStr);
}
//获取模块名称
String moduleName = logAnnotation.moduleName();
//获取操作名称
String operate = logAnnotation.operate();
userLog.setModuleName(moduleName);
userLog.setOperate(operate);
userLog.setClassName(targetName);
userLog.setMethodName(methodName);
userLog.setLogId(IdUtil.genPrimaryKey());
userLog.setTime(new Date());
userLog.setIp(IpUtil.getIpAddr(request));
userLog.setUserId(userId);
SysUserLogService userLogService = (SysUserLogService) SpringUtil.getBean ("sysUserLogService");
userLogService.addUserLog(userLog);
break;
}
}
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
工具类:
package com.tzc.webapi.util;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateUtil {
public static Date string2Date(String time) {
try {
Date date = new Date();
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
if (time.length() <= 10) {
time = time + " 00:00:00";
}
date = sdf.parse(time);
return date;
} catch (ParseException e) {
e.printStackTrace();
return null;
}
}
/**
* @param date 时间对象
* @param hms 是否显示时分秒
* @return
*/
public static String date2String(Date date, Boolean hms) {
DateFormat sdf;
if (hms) {
sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
} else {
sdf = new SimpleDateFormat("yyyy-MM-dd");
}
String time = sdf.format(date);
return time;
}
public static Timestamp string2Timestamp(String time) {
Timestamp ts = new Timestamp(System.currentTimeMillis());
if (time.length() <= 10) {
time = time + " 00:00:00";
}
ts = Timestamp.valueOf(time);
return ts;
}
/**
* @param ts 时间戳对象
* @param hms 是否显示时分秒
* @return
*/
public static String timestamp2String(Timestamp ts, Boolean hms) {
DateFormat sdf;
if (hms) {
sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
} else {
sdf = new SimpleDateFormat("yyyy-MM-dd");
}
String tsStr = "";
tsStr = sdf.format(ts);
return tsStr;
}
public static Date timestamp2Date(Timestamp ts) {
Date date = new Date();
date = ts;
return date;
}
public static Timestamp date2Timestamp(Date date) {
String time = "";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
time = sdf.format(date);
Timestamp ts = Timestamp.valueOf(time);
return ts;
}
/**
* 计算两个时间之间的小时差
* start - stop
*
* @param start 开始时间
* @param stop 结束时间
* @return
*/
public static Long countHour(Date start, Date stop) {
long diff = start.getTime() - stop.getTime();
long hour = diff / (60 * 60 * 1000);
return hour;
}
/**
* 计算两个时间之间的分钟数差
* start - stop
*
* @param start 开始时间
* @param stop 结束时间
* @return
*/
public static Long countMinute(Date start, Date stop) {
long diff = start.getTime() - stop.getTime();
long min = diff / (60 * 1000);
return min;
}
/**
* 计算两个时间之间的秒数差
* start - stop
*
* @param start 开始时间
* @param stop 结束时间
* @return
*/
public static Long countSecond(Date start, Date stop) {
long diff = start.getTime() - stop.getTime();
long sec = diff / 1000;
return sec;
}
/**
* 按天增加或减时间
*
* @param date
* @param days 增减的天数
* @param hms 是否显示时分秒
* @param isAdd 加减标识,false 是减,true是加
* @return
*/
public static String addOrMinusDate(Date date, int days, Boolean hms, Boolean isAdd) {
long d = (long) days;
SimpleDateFormat df = null;
if (hms) {
df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
} else {
df = new SimpleDateFormat("yyyy-MM-dd");
}
if (!isAdd) {
return df.format(new Date(date.getTime() - (d * 24 * 60 * 60 * 1000)));
} else {
return df.format(new Date(date.getTime() + (d * 24 * 60 * 60 * 1000)));
}
}
/**
* 判断两个日期是否同年同月
*
* @param date1 时间1
* @param date2 时间2
* @return
*/
public static boolean equals(Date date1, Date date2) {
Calendar calendar1 = Calendar.getInstance();
calendar1.setTime(date1);
Calendar calendar2 = Calendar.getInstance();
calendar2.setTime(date2);
return calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR)
&& calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH);
}
}
package com.tzc.webapi.util;
import java.util.UUID;
/**
* @auther wangzhiyun
* @data
**/
public class IdUtil {
public static String genPrimaryKey() {
return UUID.randomUUID().toString().replace("-", "");
}
}
package com.tzc.webapi.util;
import javax.servlet.http.HttpServletRequest;
/**
* @author wangzhiyun
* @date 2019-04-25 12:02
*/
public class IpUtil {
public static String getIpAddr(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip==null||ip.length()==0||"unknown".equalsIgnoreCase(ip)){
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip==null||ip.length()==0||"unknown".equalsIgnoreCase(ip)){
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip==null||ip.length()==0||"unknown".equalsIgnoreCase(ip)){
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip==null||ip.length()==0||"unknown".equalsIgnoreCase(ip)){
ip = request.getRemoteAddr();
}
return ip;
}
}
package com.tzc.webapi.util;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class SpringUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext; //Spring应用上下文环境
/**
* 实现ApplicationContextAware接口的回调方法,设置上下文环境
* @param applicationContext
* @throws BeansException
*/
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringUtil.applicationContext = applicationContext;
}
/**
* @return ApplicationContext
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 获取对象
* @param name
* @return Object 一个以所给名字注册的bean的实例
* @throws BeansException
*/
public static Object getBean(String name) throws BeansException {
return applicationContext.getBean(name);
}
/**
* 获取类型为requiredType的对象
* 如果bean不能被类型转换,相应的异常将会被抛出(BeanNotOfRequiredTypeException)
* @param name bean注册名
* @param requiredType 返回对象类型
* @return Object 返回requiredType类型对象
* @throws BeansException
*/
public static Object getBean(String name, Class requiredType) throws BeansException {
return applicationContext.getBean(name, requiredType);
}
public static T getBean(Class clazz){
return applicationContext.getBean(clazz);
}
/**
* 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
* @param name
* @return boolean
*/
public static boolean containsBean(String name) {
return applicationContext.containsBean(name);
}
/**
* 判断以给定名字注册的bean定义是一个singleton还是一个prototype。
* 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
* @param name
* @return boolean
* @throws NoSuchBeanDefinitionException
*/
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
return applicationContext.isSingleton(name);
}
/**
* @param name
* @return Class 注册对象的类型
* @throws NoSuchBeanDefinitionException
*/
public static Class getType(String name) throws NoSuchBeanDefinitionException {
return applicationContext.getType(name);
}
/**
* 如果给定的bean名字在bean定义中有别名,则返回这些别名
* @param name
* @return
* @throws NoSuchBeanDefinitionException
*/
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
return applicationContext.getAliases(name);
}
}
spring-mybatis.xml
业务方法加注解
package com.tzc.webapi.service;
import com.tzc.webapi.anon.LogAnnotation;
import com.tzc.webapi.bean.Book;
import com.tzc.webapi.dao.masterBook.BookMapper;
import com.tzc.webapi.dao.masterBook.TableMapper;
import com.tzc.webapi.service.interfece.BookServiceImp;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Component
@Transactional
public class BookService implements BookServiceImp {
@Autowired
private BookMapper bookMapper;
@Autowired
private TableMapper tableMapper;
private static Logger logger = org.slf4j.LoggerFactory.getLogger(BookService.class);
@LogAnnotation(moduleName = "book模块",operate = "id查询")
public Book getBookById(Long id,String tableName) {
try {
String s = tableMapper.selectByName(tableName);
System.out.println(s);
Book book = bookMapper.selectByPrimaryKey(id);
return book;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public Boolean saveOneBook(Book book) {
try {
bookMapper.insert(book);
logger.info("插入book成功");
return true;
} catch (Exception e) {
e.printStackTrace();
logger.info("插入book失败");
return false ;
}
}
//分页查询
@LogAnnotation(moduleName = "book模块",operate = "分页查询")
public List findBooksByPage(int page, int rows) {
int index=(page-1)*rows;
return bookMapper.selectBookByPage(index,rows);
}
//总条数
@LogAnnotation(moduleName = "book模块",operate = "书籍总数")
public Integer CountBooks() {
return bookMapper.selectCountBook();
}
//通过id删除
@LogAnnotation(moduleName = "book模块",operate = "通过id删除")
public Boolean removeById(Long id) {
int i = bookMapper.deleteByPrimaryKey(id);
if (i==1) {
logger.info("删除成功");
return true;
}
logger.info("删除失败");
return false;
}
}
测试:执行方法