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文件中,然后才能生效