环绕通知的特点:
- 必须传入ProceedingJoinPoint对象,调用其proceed()方法来手动执行切入点,否则什么也不执行
切入点:
package com.dwb.service.impl;
@Service
public class UserServiceImpl implements IUserService {
@Autowired
private IUserDao userDao;
@Override
public User findUserById(int id) {
System.out.println("方法被执行");
return userDao.findUserById(id);
}
}
切面类:
package com.dwb.aop;
@Component
@Aspect
public class LogAspect {
@Around("execution(* com.dwb.service.impl.*.*(..))")
public void around(ProceedingJoinPoint pjp) {
try {
pjp.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
}
运行结果:
方法被执行
- proceed()方法相对于是一个代理方法,如果写了其他四种通知,将会相应的执行
package com.dwb.aop;
@Component
@Aspect
public class LogAspect {
@Before("execution(* com.dwb.service.impl.*.*(..))")
public void before(){
System.out.println("前置通知");
}
@After("execution(* com.dwb.service.impl.*.*(..))")
public void after(){
System.out.println("后置通知");
}
@AfterThrowing("execution(* com.dwb.service.impl.*.*(..))")
public void throwing() {
System.out.println("异常通知");
}
@AfterReturning("execution(* com.dwb.service.impl.*.*(..))")
public void returning() {
System.out.println("返回通知");
}
@Around("execution(* com.dwb.service.impl.*.*(..))")
public void around(ProceedingJoinPoint pjp) {
try {
pjp.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
}
运行结果
前置通知
方法被执行
返回通知
后置通知
建议:环绕通知不要和其他四种通知一起使用,而是把其他四种通知的代码都放在环绕通知的方法里面(和我们自己写的静态代理是一样的)
@Around("execution(* com.dwb.service.impl.*.*(..))")
public void around(ProceedingJoinPoint pjp) {
// 这里写前置通知
try {
pjp.proceed(); // 这里执行被代理的方法(切入点)
// 这里写返回通知
} catch (Throwable throwable) {
// 这里写异常通知
} finally {
// 这里写后置通知
}
}