Spring AOP 记录Controller 和 Service 层做日志

1)对service层做操作日志时,只对增,删,改等操作记录。
记录的内容主要有:
操作人 所属部门 动作 动作操作对象 操作前内容 操作后内容 IP 操作时间
冰冰 销售部 增加 角色 “” 添加的内容 ip 2018-05-11 11:56:30

为了记录这样的内容,在service中添加AOP的配置文件。xml文件配置如下

   <bean id="systemLogAdvice" class="com.lenovo.thinkiot.mybatis.common.aop.SystemLogAdvice" />
   <aop:config>
   <aop:aspect ref="systemLogAdvice">
      <aop:pointcut id="systemLogPointCut" expression="
            execution(* com.lenovo.thinkiot.service.alarm..add*(..))
         or execution(* com.lenovo.thinkiot.service.alarm..update*(..))
         or execution(* com.lenovo.thinkiot.service.alarm..delete*(..))

         or execution(* com.lenovo.thinkiot.service.account.MiniSsUserServiceImpl.saveUser(..))
         or execution(* com.lenovo.thinkiot.service.account.MiniSsUserServiceImpl.updateSsUser(..))
         or execution(* com.lenovo.thinkiot.service.account.LaoSsAccountServiceImpl.deleteAcconut(..))

         or execution(* com.lenovo.thinkiot.service.account.MiniSsRoleServiceImpl.saveSsRole(..))
         or execution(* com.lenovo.thinkiot.service.account.MiniSsRoleServiceImpl.updateSsRole(..))
         or execution(* com.lenovo.thinkiot.service.account.LaoSsRoleServiceImpl.deleteRole(..))

         or execution(* com.lenovo.thinkiot.service.account.LaoDepartServiceImpl.saveDept(..))
         or execution(* com.lenovo.thinkiot.service.account.LaoDepartServiceImpl.updateDept(..))
         or execution(* com.lenovo.thinkiot.service.account.LaoDepartServiceImpl.deleteDept(..))

         or execution(* com.lenovo.thinkiot.service.account.LaoTagServiceImpl.saveTag(..))
         or execution(* com.lenovo.thinkiot.service.account.LaoTagServiceImpl.updateTag(..))
         or execution(* com.lenovo.thinkiot.service.account.LaoTagServiceImpl.deleteTag(..))" />
      <aop:around method="doSaveLog" pointcut-ref="systemLogPointCut"></aop:around>
   </aop:aspect>
   </aop:config>

<!-- 定义aspectj -->
<aop:aspectj-autoproxy proxy-target-class="true" />

bean:指定日志类,做具体的记录内容
aop:配置切入点,对哪些类,哪些方法做记录。其余的方法,不做记录,使用CGLIB方式

我的困扰点 :我之前的操作是记录所有以savexxx , updatexxx, deletexxx等名称开头的所有的方法,但后来操作中发现,对我们项目的代码,有点问题。
比如修改角色信息时,虽然切入点是deletexxx,但当删除具体的角色时,每个角色都会删除一次,因此,日志也就记录一次,导致一次操作,记下了多条记录。而有的是没有获取到内容的,这就不是我想要的了。然后,毅然决定具体到类,具体到方法,删除时,就指定具体的删除方法。增加,修改时,都一样,指定到具体的类,方法。然后发现,操作一次,记录一次。是我想要的。
我不需要知道,具体删了哪个角色,我只需要知道,删除前有哪些角色就好

具体执行的日志类:SystemLogAdvice
方法为 public Object doSaveLog(ProceedingJoinPoint pjp) throws Throwable{}
因为我配置的类型是 around 环绕类型,所以,参数用的ProceedingJointPoint类型
这个类,就可以获取到进入到目标方法中的所有信息。
public Object doSaveLog(ProceedingJoinPoint pjp) throws Throwable{
Object obj = pjp.proceed();
retrun obj;
}
有了return obj,才表示,这个环绕方法正真执行了。
在这里,做添加,删除都很好做。因为pjp.proceed()方法执行的就是具体的添加,删除操作。
但做修改的时候,我卡住了。传进来的参数中有对应的id,但我不知道怎么通过这个id,得到库中对应的数据,我想不明白,我一直以为环绕方法,所有的信息都是通过ProceedingJoinPoint类型来获取,网上搜,也没见到有修改,还要获取修改前和修改后的内容。我在群里问了下,大家说,你平时是怎么通过id取详情的,这里就怎么取。我一直没明白,我当时想着,通过id取详情,我有专门的根据id查询详情的方法,比如selectDeptById(),但这个方法,我在这个操作日志类该怎么用?我一直没明白,一直在问。我还在说,这个类中,我怎样才能取到selectDeptById()这个方法呢。我一直不知道怎么做。
晚上下班回家路上,想到了这句话,突然明白。人家说,之前怎么用,这里就怎么用的意思。将类引注入进来,类有了,类中的方法也就获取到了。

private static final Logger LOG = LoggerFactory.getLogger(SystemLogAdvice.class);

@Autowired
private LaoSystemOperationLogService laoSystemOperationLogService;
//角色修改
@Autowired
private LaoSsRoleService laoSsRoleService;
// 账号修改
@Autowired
private LaoSsAccountService laoSsAccountService;
//部门
@Autowired
private LaoDepartMapper laoDepartMapper;
//标签
@Autowired
private LaoTagMapper laoTagMapper;

想明白了可以注入其他的类,这突然就觉得好办了。有方法,有id,想要的信息都能获取到。
然后就只针对不同的方法,做不同的操作,用了if 判断。总觉得还有其他更好的比较方法,但我不知道怎么用,只用了最low 的方法。
if (mathodName.startsWith("add") || mathodName.startsWith("save")) {
    laoSystemOperationLogDto.setAction("增加");
    //变更前
    laoSystemOperationLogDto.setInputParams(null);
    laoSystemOperationLogDto.setOutputParams(content.getBytes());
    if(StringUtils.isNotBlank(laoSystemOperationLogDto.getOperationUser())){
        laoSystemOperationLogService.save(laoSystemOperationLogDto);
    }
}
//角色更新
if(MnoDictionary.UPDATESSROLE_METHOD.equals(mathodName)){
    laoSystemOperationLogDto.setAction("修改");
    laoSystemOperationLogDto.setOperand("角色");
    laoSystemOperationLogDto.setOutputParams(content.getBytes());

    Object id = getParam(args, MnoDictionary.UPDATESSROLE_ID);
    LaoSsRoleDto laoSsRoleDto = laoSsRoleService.getRoleDetailById((Long)id);
    laoSystemOperationLogDto.setInputParams(JsonMapper.toString(laoSsRoleDto).getBytes());
    laoSystemOperationLogService.save(laoSystemOperationLogDto);
}
if(MnoDictionary.UPDATESSUSER_METHOD.equals(mathodName)) {
    laoSystemOperationLogDto.setAction("修改");
    laoSystemOperationLogDto.setOperand("账号");
    laoSystemOperationLogDto.setOutputParams(content.getBytes());

    Object id = getParam(args, MnoDictionary.UPDATESSUSER_ID);
    LaoSsAccountDto laoSsAccountDto = laoSsAccountService.selectUserById((Long)id);
    laoSystemOperationLogDto.setInputParams(JsonMapper.toString(laoSsAccountDto).getBytes());
    laoSystemOperationLogService.save(laoSystemOperationLogDto);
}
if(MnoDictionary.UPDATEDEPT_METHOD.equals(mathodName)) {
    laoSystemOperationLogDto.setAction("修改");
    laoSystemOperationLogDto.setOperand("部门");
    laoSystemOperationLogDto.setOutputParams(content.getBytes());
    Object id = getParam(args, MnoDictionary.UPDATEDEPT_ID);
    LaoDepartExample laoDepartExample = new LaoDepartExample();
    LaoDepartExample.Criteria criteria = laoDepartExample.createCriteria();
    criteria.andDeptIdEqualTo((Integer)id);
    List<LaoDepart> list = laoDepartMapper.selectByExample(laoDepartExample);
    laoSystemOperationLogDto.setInputParams(JsonMapper.toString(list.get(0)).getBytes());
    laoSystemOperationLogService.save(laoSystemOperationLogDto);
}
//标签更新
if(MnoDictionary.UPDATETAG_METHOD.equals(mathodName)) {
    laoSystemOperationLogDto.setAction("修改");
    laoSystemOperationLogDto.setOperand("标签");
    laoSystemOperationLogDto.setOutputParams(content.getBytes());
    Object id = getParam(args, MnoDictionary.UPDATETAG_ID);
    LaoTagExample laoTagExample = new LaoTagExample();
    LaoTagExample.Criteria criteria = laoTagExample.createCriteria();
    criteria.andTagIdEqualTo((Integer)id);
    List<LaoTag> list =  laoTagMapper.selectByExample(laoTagExample);
    laoSystemOperationLogDto.setInputParams(JsonMapper.toString(list.get(0)).getBytes());
    laoSystemOperationLogService.save(laoSystemOperationLogDto);
}
到这里,service层的操作记录就算完成了。
最需要记录的思路是:这个类中,可以注入其他需要的类,来使用想要用的方法!!!

2)Controller 层的AOP 做日志
这层做日志时,也遇到了些问题,
在xml 文件中配置,发现不起作用。
用注解直接在类上配置,还是不起作用。
这就尴尬了。在网上搜,比较配置,也没发现有问题。但就是不起作用。
然后换了关键词搜索,Controller 层AOP配置不起作用 ,然后才发现,自己的错误在哪
Controller层的配置,应该放在Spring-mvc文件中,然后才能生效



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值