SpringBoot应用AOP进行日志记录

作用

将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。


注解

@Aspect  定义切面类
@Component 定义配置
@Pointcut  定义切入点
@AfterReturning 方法执行后执行的方法

应用

基于SpringBoot实现接口日志记录


定义切面类

@Aspect
@Component
public class UserAspect {

    Logger LOGGER = LoggerFactory.getLogger(this.getClass());

    @Autowired
    ISrmUserLogService srmUserLogService;

    @Pointcut("@annotation(com.purchasecloud.srm.annotation.UserOperation)")
    public void aspectaMethod() {

    }
    
    @AfterReturning(value = "@annotation(userOperation)", returning = "result")
    public void doAfterReturning(JoinPoint point, Object result, UserOperation userOperation) throws Exception {
        //用户操作日志记录
        ResponseResult responseResult = srmUserLogService.addSrmUserLogOfAop(point, result, userOperation);
        LOGGER.debug(DateUtils.getCurrentTime()+"--AOP添加日志返回结果:"+responseResult);
    }
}


用户注解

/**
 * 用户注解
 * 功能:作用于controller接口,用于aop记录日志使用
 */
@Retention(RetentionPolicy.RUNTIME)  //RetentionPolicy.RUNTIME 表示注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在
@Target({ElementType.METHOD})       //ElementType.METHOD 表示该注解是用来描述方法的
@Documented
public @interface UserOperation {
    //模块名
    String moduleName() default "";
    //操作记录
    String operationRecord() default "";
}


日志Service业务处理

/**
 * 

* 服务实现类 *

* * @author shenyidong * @since 2019-07-26 */
@Service public class SrmUserLogServiceImpl extends ServiceImpl<SrmUserLogMapper, SrmUserLog> implements ISrmUserLogService { @Autowired SrmUserLogMapper srmUserLogMapper; @Override public ResponseResult addSrmUserLogOfAop(JoinPoint point, Object result, UserOperation userOperation) { SrmUserLog srmUserLog = new SrmUserLog(); //ID srmUserLog.setId(StringUtils.uuid()); //用户名 //模块名 srmUserLog.setModuleName(userOperation.moduleName()); //操作记录 srmUserLog.setOperation(userOperation.operationRecord()); //操作时间 srmUserLog.setOperationTime(DateUtils.getCurrentDate()); //类名 srmUserLog.setClassName(point.getTarget().getClass().getName()); //方法名 srmUserLog.setMethodName(point.getSignature().getName()); //请求url //请求参数 //请求值 MethodSignature signature = (MethodSignature) point.getSignature(); //获取签名对象 Method method = signature.getMethod(); //获取方法 ParameterNameDiscoverer pnd = new DefaultParameterNameDiscoverer(); Object[] args = point.getArgs(); String[] parameterNames = pnd.getParameterNames(method); //请求字段名 JSONObject object = new JSONObject(); for (int i = 0; i < parameterNames.length; i++) { object.put(parameterNames[i],args[i]); } srmUserLog.setParams(object.toJSONString()); //ip //地址 int res = srmUserLogMapper.insert(srmUserLog); return HandleResponseResult.checkAddValue(res); } }


用户注解作用在controller层

@Api(value = "采购云SRM系统用户模块接口", description = "采购云SRM系统用户模块接口")
@RestController
@RequestMapping("/srmuser")
@CrossOrigin //解决跨域
public class SrmUserController {

    private static final String MODULE_NAME = "用户";

    @Autowired
    ISrmUserService srmUserService;

    @Autowired
    OrderService orderService;

    @UserOperation(moduleName= MODULE_NAME,operationRecord = "根据账号密码查询" + MODULE_NAME)
    @ApiOperation("根据账号密码查询" + MODULE_NAME)
    @PostMapping(value = "/login")
    public ResponseResult queryUserByNameAndPassword(@RequestBody SrmUser srmUser) {
        if (StringUtils.isBlank(String.valueOf(srmUser.getUserNumber())) || StringUtils.isBlank(srmUser.getUserPassword())) {
            throw new ParameterIsNullException();
        }
        return srmUserService.login(srmUser);
    }
}


UserOperation

UserOperation注解作用于接口上,aop切面类在切入点时会扫描到,aop业务类可以获取到接口上的UserOperation属性值。

你可能感兴趣的:(SpringBoot)