自定义注解实现日志控制
1、数据库准备
CREATE TABLE `operation_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`operate_class` varchar(200) DEFAULT NULL COMMENT '操作类',
`operate_method` varchar(200) DEFAULT NULL COMMENT '操作方法',
`return_class` varchar(200) DEFAULT NULL COMMENT '返回值类型',
`operate_user` varchar(20) DEFAULT NULL COMMENT '操作用户',
`operate_time` varchar(20) DEFAULT NULL COMMENT '操作时间',
`param_and_value` varchar(500) DEFAULT NULL COMMENT '请求参数名及参数值',
`cost_time` bigint(20) DEFAULT NULL COMMENT '执行方法耗时, 单位 ms',
`return_value` varchar(200) DEFAULT NULL COMMENT '返回值',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2、entity
2.1、OperationLog :操作日志
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OperationLog {
private Integer id;
//返回值
private String returnValue;
//返回值类型
private String returnClass;
//操作人
private String operateUser;
//操作时间
private String operateTime;
//参数值 , 键值对形式
private String paramAndValue;
//操作的类
private String operateClass;
//操作的方法
private String operateMethod;
//操作耗时
private Long costTime;
}
2.2、PageResult 返回结果
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageResult {
private Long total;
private List dataList;
}
3、Service
@Service
@Transactional
public class OperationLogService {
@Autowired
private OperationLogMapper operationLogMapper;
public void insert(OperationLog operationLog){
operationLogMapper.insert(operationLog);
}
public PageResult findByPage(Map paramMap , Integer pageNum , Integer rows){
if(paramMap ==null){
paramMap = new HashMap();
}
paramMap.put("start" , (pageNum-1)*rows);
paramMap.put("rows",rows);
Object costTime = paramMap.get("costTime");
if(costTime != null){
if("".equals(costTime.toString())){
paramMap.put("costTime",null);
}else{
paramMap.put("costTime",new Long(costTime.toString()));
}
}
long start_time = System.currentTimeMillis();
Long count = operationLogMapper.countByCondition(paramMap);
long end_time = System.currentTimeMillis();
System.out.println("Count Cost Time : " + (end_time - start_time) + " ms");
List<OperationLog> list = operationLogMapper.findByCondition(paramMap);
long end_time2 = System.currentTimeMillis();
System.out.println("Query Cost Time : " + (end_time2 - end_time) + " ms");
return new PageResult(count,list);
}
}
4、mapper和xml
@Mapper
public interface OperationLogMapper {
void insert(OperationLog operationLog);
/**
* 查询结果列表
*/
List<OperationLog> findByCondition(Map paramMap);
/**
* 获取符合条件的总记录数
* @param paramMap
* @return
*/
Long countByCondition(Map paramMap);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.zhb.mapper.OperationLogMapper" >
<insert id="insert" parameterType="operationLog">
INSERT INTO operation_log(id,return_value,return_class,operate_user,operate_time,param_and_value,operate_class,operate_method,cost_time)
VALUES(NULL,#{returnValue},#{returnClass},#{operateUser},#{operateTime},#{paramAndValue},#{operateClass},#{operateMethod},#{costTime})
</insert>
<select id="countByCondition" resultType="long" parameterType="map">
SELECT COUNT(*) FROM `operation_log`
<include refid="query_where"></include>
</select>
<select id="findByCondition" parameterType="map" resultType="operationLog">
SELECT
o.id,
o.operate_class AS operateClass ,
o.operate_method AS operateMethod,
o.return_class AS returnClass,
o.operate_user AS operateUser,
o.operate_time AS operateTime,
o.param_and_value AS paramAndValue,
o.cost_time AS costTime,
o.return_value AS returnValue
FROM
operation_log o,
(SELECT id FROM operation_log
<include refid="query_where"></include>
ORDER BY id LIMIT #{start} , #{rows}) a
where
o.id = a.id
</select>
<sql id="query_where">
<where>
<if test="operateUser != null and operateUser != ''">
and operate_user = #{operateUser}
</if>
<if test="operateMethod != null and operateMethod != ''">
and operate_method = #{operateMethod}
</if>
<if test="returnClass != null and returnClass != ''">
and return_class = #{returnClass}
</if>
<if test="costTime != null">
and cost_time = #{costTime}
</if>
</where>
</sql>
</mapper>
5、AOP相关
5.1、自定义注解类
自定义注解,标示方法需不需要进行记录日志,如果该方法在访问时需要记录日志,则在该方法上标示该注解既可。
@Inherited
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OperateLog {
}
5.2、切面类
@Component
@Aspect
public class OperateAdvice {
private static Logger log = Logger.getLogger(OperateAdvice.class);
@Autowired
private OperationLogService operationLogService;
//@Around("execution(* com.zhb.service.*.*(..)) && @annotation(OperateLog)")
//public Object insertLogAround(ProceedingJoinPoint pjp) throws Throwable{
@Around("execution(* com.zhb.service.*.*(..)) && @annotation(operateLog)")
public Object insertLogAround(ProceedingJoinPoint pjp, OperateLog operateLog) throws Throwable{
System.out.println(" *********************************** 记录日志 [start] ****************************** ");
OperationLog op = new OperationLog();
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
op.setOperateTime(sdf.format(new Date()));
op.setOperateUser(DataUtils.getRandStr(8));// 从Session中获取当前登录用户 .
op.setOperateClass(pjp.getTarget().getClass().getName());
op.setOperateMethod(pjp.getSignature().getName());
Object[] args = pjp.getArgs();
op.setParamAndValue(Arrays.toString(args));
long start_time = System.currentTimeMillis();
//放行
Object object = pjp.proceed();
long end_time = System.currentTimeMillis();
op.setCostTime(end_time - start_time);
if(object != null){
op.setReturnClass(object.getClass().getName());
op.setReturnValue(object.toString());
}else{
op.setReturnClass("java.lang.Object");
op.setReturnValue("void");
}
log.error(JsonUtils.obj2JsonString(op));
operationLogService.insert(op);
System.out.println(" *********************************** 记录日志 [end] ****************************** ");
return object;
}
}
6、Utils
6.1、DataUtils:模拟用户
public class DataUtils {
public static int getNum(int start,int end) {
return (int)(Math.random()*(end-start+1)+start);
}
public static String getRandStr(int num){
String strs = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
StringBuffer buff = new StringBuffer();
for(int i=1;i<=num;i++){
char str = strs.charAt((int)(Math.random() * 26));
buff.append(str);
}
return buff.toString();
}
}
6.2、JsonUtils:json处理
@SuppressWarnings("all")
public class JsonUtils {
public static Map<String, Object> json2Map(String json) throws IOException {
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(json, Map.class);
}
public static String obj2JsonString(Object obj) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(obj);
}
}
7、POM
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>