昨天想用aop实现用户日志功能,把用户每一步操作记录下来,我的想法是把controller作为切点,然后进行切割。
想好之后就开始写代码啊,代码很快写好了,
@Component
@Aspect
public class LogAop {
private Logger logger = LoggerFactory.getLogger(LogAop.class);
/**
* controller包下的所有类
* 切点
*/
@Pointcut(value = "execution(* com.codeliu.controller.*.*(..))")
private void pointcutLog() {
}
/**
* 记录用户操作,作为切面
*/
@Before(value = "pointcutLog()")
@Transactional
public ResultData<Integer> addLog(JoinPoint joinpoint,UserOperationLog userOperationLog) {
System.out.println("我进来了!!!");
// 。。。。。。
}
}
进行测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-web.xml","classpath:spring/spring-dao.xml","classpath:spring/spring-service.xml"})
public class TestLogAop {
@Autowired
private LogAop logAop;
private Logger logger = LoggerFactory.getLogger(TestLogAop.class);
@Test
public void testAop() {
logger.info("logAop={}" + logAop);
}
}
运行测试方法发现一直报错error at ::0 formal unbound in pointcut,连类的实例都创建失败
首先考虑一下是不是JoinPoint类导错了包,是import org.aspectj.lang.JoinPoint;,确认没错之后再往下看
通过查资料发现,当切面中的方法有参数的时候,在注解中得加上参数
比如上面的代码
@Before(value = "pointcutLog()")
@Transactional
public ResultData<Integer> addLog(JoinPoint joinpoint,UserOperationLog userOperationLog) {
System.out.println("我进来了!!!");
// 。。。。。。
}
方法有两个参数,如果有除了JoinPoint类型的其他参数,则得修改如下
@Before(value = "pointcutLog() && args(userOperationLog)")
@Transactional
public ResultData<Integer> addLog(JoinPoint joinpoint,UserOperationLog userOperationLog) {
System.out.println("我进来了!!!");
// 。。。。。。
}
最后问题解决,不过发现貌似没切成功,可能哪里还有问题。