做系统的日志管理, 需要对管理员的操作进行保存.
想法是使用自定义注解+AOP , 在Controller中的方法贴自定义注解是可以切入的,但是在ServiceImpl的方法中贴注解, 却不切入.
有大牛说下,怎么解决吗?serviceImpl方法中使用了@Transactional 事务注解. 有人说是和事务aop冲突了,下面是LogAspect类@Component
@Aspect
public class ConsoleSystemLogAspect { private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleSystemLogAspect.class); @Autowired
private IConsoleSystemLogService consoleSystemLogService; @Pointcut("@annotation(com.inesv.root.common.annotation.RecordLog)")
public void logAspect(){}
@Before("logAspect()")
public void saveSystemLog(JoinPoint point) {
ConsoleSystemLog log = new ConsoleSystemLog();
// 获取Request
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
// 设置ip
String ipAddress = request.getRemoteAddr();
log.setIpAddress(ipAddress);
// 设置当前登录用户的用户名和id
ConsoleUser currentUser = (ConsoleUser) SecurityUtils.getSubject().getPrincipal();
log.setOpId(currentUser.getId());
log.setOpName(currentUser.getUsername());
// 设置时间
log.setOpTime(new Date());
// 设置方法
String simpleName = point.getSignature().getDeclaringType().getSimpleName();
String methodName = point.getSignature().getName();
String function = simpleName + "." + methodName;
log.setFunction(function);
// 设置参数
Object[] args = point.getArgs();
log.setParams(JSON.toJSONString(args));
LOGGER.info("操作日志:{}",JSON.toJSONString(log));
// 保存日志
consoleSystemLogService.save(log); }
}
这是UserServiceImpl@Service
public class ConsoleUserServiceImpl implements IConsoleUserService { @Autowired
private ConsoleUserMapper consoleUserMapper;
@Autowired
private ConsoleUserRoleMapper consoleUserRoleMapper; @Override
@RecordLog
@Transactional(rollbackFor = {Exception.class, RuntimeException.class},propagation = Propagation.NESTED)
public void delete(Long id) {
AssertUtils.isIdNull(id, "用户id不能为空", Context.CODE_ARGS_ERROR);
// 逻辑删除用户
consoleUserMapper.updateDeleteStatus(id);
}
}
注解类@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogsDescribe { /**
* 接口名称
* @return
*/
String value() default "";
}
Aspect@Aspect
@Component
public class LogsDescribeAspect { private static final Logger logger = LoggerFactory.getLogger(LogsDescribeAspect.class);
@Resource(name="operationLogService")
private OperationLogService operationLogService;
@Pointcut("@annotation(com.huangbl.blog.config.LogsDescribe)")
private void cut() {
}
@Before("cut()")
public void before(JoinPoint joinPoint) {
logger.info("LogsDescribe...before");
}
@After("cut()")
public void after(JoinPoint joinPoint) {
logger.info("LogsDescribe...after");
}
}
service中使用注解的方法和你的一样,代码我就不发了最后就是Aspect自动代理,在spring配置文件中加上(在spring boot中只需要在服务启动类上加上@EnableAspectJAutoProxy)<aop:aspectj-autoproxy proxy-target-class="true" />