您的位置:首页 > 编程语言 > ASP

SpringBoot 使用@Aspect进行日志管理(基于反射代理模式)

2017-10-09 11:27 891 查看
1、添加maven依赖注解

<!--springBoot 的aop-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--MySQL 相关Jar包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<!-- 判空StringUtils-->
<dependency>
<groupId>org.apache.directory.studio</groupId>
<artifactId>org.apache.commons.lang</artifactId>
<version>2.6</version>
</dependency>
<!--http-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>


2、添加数据库表

DROP TABLE IF EXISTS `journal`;
CREATE TABLE `journal` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '日志id',
`uid` int(11) NOT NULL COMMENT '用户id',
`modularType` int(2) NOT NULL COMMENT '模块类型',
`operationType` int(2) NOT NULL COMMENT '操作类型:0:增/1:删/2:改/3:关闭/4:移动',
`operationTime` datetime NOT NULL COMMENT '操作时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


3、日志实体类

import org.springframework.stereotype.Component;

import java.util.Date;

/**
* 日志实体类
* Created by 陈梓平 on 2017/8/12.
*/
@Component
public class JournalInfo {
/**日志id*/
private Integer id;
/**用户id*/
private Integer uid;
/**模块类型*/
private Integer modularType;
/**操作类别*/
private Integer operationType;
/**操作时间*/
private Date operationTime;

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public Integer getUid() {
return uid;
}

public void setUid(Integer uid) {
this.uid = uid;
}

public Integer getModularType() {
return modularType;
}

public void setModularType(Integer modularType) {
this.modularType = modularType;
}

public Integer getOperationType() {
return operationType;
}

public void setOperationType(Integer operationType) {
this.operationType = operationType;
}

public Date getOperationTime() {
return operationTime;
}

public void setOperationTime(Date operationTime) {
this.operationTime = operationTime;
}
}


4、日志添加Mapper

/**
* 日志管理
* Created by 陈梓平 on 2017/8/12.
*/
public interface JournalMapper {
/**日志添加*/
int addJournalInfo(JournalInfo journalInfo);
}

<?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.chen.mapper.JournalMapper">
<!--添加日志信息-->
<insert id="addJournalInfo">
INSERT INTO journal  (uid,modularType,operationType,operationTime)
VALUES (10086,#{modularType},#{operationType},NOW())
</insert>
</mapper>


5、日志工具类

import com.chen.mapper.JournalMapper;
import com.chen.model.JournalInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

/**
* 日志工具类
* Created by 陈梓平 on 2017/9/11.
*/
@Component
@Transactional
public class JournalUtils {

@Autowired
private JournalMapper jouUtilsJournalMapper;
@Autowired
private JournalInfo journalInfo;

/**
* 添加日志
* @param modeularType
* @param operationType
*/
public void addJournalInfo(int modeularType,int operationType,int uid) {
journalInfo.setModularType(modeularType);
journalInfo.setOperationType(operationType);
journalInfo.setUid(uid);
jouUtilsJournalMapper.addJournalInfo(journalInfo);
}
}


6、静态类(包括模块和操作)

/**
* 静态信息
* Created by Administrator on 2017/8/12.
*/
public class StaticInfo {
/**---------------------------------------  模块类型  --------------------------------------------*/
//模块1
public static final int MODEULARTTYPE_FIRST= 1;

/**---------------------------------------  操作类别  --------------------------------------------*/
//增加
public static final int OPERATIONTYPE_ADD = 0;
//删除
public static final int OPERATIONTYPE_UPDATE = 1;
//修改
public static final int OPERATIONTYPE_DELETE = 2;
//开启
public static final int OPERATIONTYPE_OPEN = 3;
//关闭
public static final int OPERATIONTYPE_CLOSE = 4;
//移动
public static final int OPERATIONTYPE_MOVER = 5;

/**--------------------------------------------   AOP代理  -------------------------------------------------------*/
public static final String AOP_OPERATION_TYPE_ADD =  "add";
public static final String AOP_OPERATION_TYPE_EDIT =  "edit";
public static final String AOP_OPERATION_TYPE_MOVE =  "move";
public static final String AOP_OPERATION_TYPE_DELETE =  "delete";
public static final String AOP_OPERATION_TYPE_OPENORCLOSE =  "openOrClose";

public static final String AOP_MODULAR_TYPE_FIRST = "Journal";

public static final String AOP_SPIT_CLASSNAME = "impl.";
public static final String AOP_SPIT_MODULAR_TYPE= "ServiceImpl";
}


7、日志切面AOP

import com.chen.enums.ResultEnum;
import com.chen.exception.CustomException;
import com.chen.staticInfos.StaticInfo;
import com.chen.utils.JournalUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.apache.commons.lang.StringUtils;
import org.springframework.transaction.annotation.Transactional;

/**
* 日志切面
* Created by 陈梓平 on 2017/9/11.
*/
@Component
@Aspect
public class JournalAspect {
/**日志输出*/
private static final Logger logger = LoggerFactory.getLogger(JournalAspect.class);

/**日志工具类*/
@Autowired
private JournalUtils aspectJournalUtils;

/**service层切面*/
private final String POINT_CUT = "execution(* com.chen.service..*(..))";

@Pointcut(POINT_CUT)
private void pointcut(){}

/**
* 后置最终通知(目标方法只要执行完了就会执行后置通知方法)
* 日志管理
* @param joinPoint
*/
@After(value = "pointcut()")
@Transactional
public void doAfterAdvice(JoinPoint joinPoint) throws CustomException {
//用的最多 通知的签名
Signature signature = joinPoint.getSignature();
//1.获取模块类型
//AOP代理类的名字(包括包名)
String declaringTypeName = signature.getDeclaringTypeName();
logger.info("AOP代理类的名字"+declaringTypeName);
//获取代理类的类名
String[] split = declaringTypeName.split(StaticInfo.AOP_SPIT_CLASSNAME);
String className = split[1];
//获取模块名
String[] modularTypeNames = className.split(StaticInfo.AOP_SPIT_MODULAR_TYPE);
String modularTypeName = modularTypeNames[0];
int modulerType = -1;
//模块类型筛选
modulerType = this.getModularType(modularTypeName, modulerType);

//2.获取操作类型
//代理的是哪一个方法
String  methodName = signature.getName();
logger.info("AOP代理方法的名字"+signature.getName());
int opreationType = -1;
opreationType = getOpreationType(joinPoint, signature, opreationType,methodName);

if (modulerType==-1&&opreationType==-1)
if (!StringUtils.isBlank(methodName)||!StringUtils.isBlank(modularTypeName))
throw new CustomException(ResultEnum.JOURNAL_LOG_ERROR);

//3.添加日志
if (modulerType!=-1&&opreationType!=-1)
//TODO 3.1 从请求获取用户id
aspectJournalUtils.addJournalInfo(modulerType,opreationType, 10086);

}
/**
* 模块类型筛选
* @param modularTypeName
* @param type
* @return
*/
private int getModularType(String modularTypeName, int type) {
//模块类型筛选
switch (modularTypeName){
case StaticInfo.AOP_MODULAR_TYPE_FIRST:
type = StaticInfo.MODEULARTTYPE_FIRST;
break;
//多模块添加
}
return type;
}
/**
* 获取操作类型
* @param joinPoint
* @param signature
* @param opreationType
* @return
*/
private int getOpreationType(JoinPoint joinPoint, Signature signature, int opreationType,String  methodName ) {
switch (methodName){
case StaticInfo.AOP_OPERATION_TYPE_ADD:
opreationType = StaticInfo.OPERATIONTYPE_ADD;
break;
case StaticInfo.AOP_OPERATION_TYPE_EDIT:
opreationType = StaticInfo.OPERATIONTYPE_UPDATE;
break;
case StaticInfo.AOP_OPERATION_TYPE_MOVE:
opreationType = StaticInfo.OPERATIONTYPE_MOVER;
break;
case StaticInfo.AOP_OPERATION_TYPE_DELETE:
opreationType = StaticInfo.OPERATIONTYPE_DELETE;
break;
case StaticInfo.AOP_OPERATION_TYPE_OPENORCLOSE:
Object[] obj = joinPoint.getArgs();
int arg = (int) obj[1];
if (arg==1)
opreationType = StaticInfo.OPERATIONTYPE_OPEN;
else
opreationType = StaticInfo.OPERATIONTYPE_CLOSE;
break;
}
return opreationType;
}
}


8、添加Controller测试

import com.chen.model.Result;
import com.chen.service.JournalService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* 日志测试
* Created by 陈梓平 on 2017/9/11.
*/
@RestController
@RequestMapping
public class JournalController {
@Autowired
private JournalService journalService;

@PostMapping(value = "journalAdd")
public Result add(){
return journalService.add();
}
}


9、添加Service测试

/**
* Created by 陈梓平 on 2017/9/11.
*/
@Service
public class JournalServiceImpl implements JournalService {
@Override
public Result add() {
return ResultUtils.success(ResultEnum.OK);
}
}


10、测试结果

1)、接口调用



2)、数据库添加日志数据



* 附件代码下载:https://git.oschina.net/CatalpaFlat/JouranlDemo.git*
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐