参考
AOP概念
-
Target(目标对象):代理的目标对象
-
Proxy (代理):一个类被 AOP 织入增强后,就产生一个结果代理类
-
Joinpoint(连接点):所谓连接点是指那些可以被拦截到的点。在spring中,这些点指的是方法,因为 spring只支持方法类型的连接点
-
Pointcut(切入点):所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义
-
Advice(通知/ 增强):所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知 分类:前置通知、后置通知、异常通知、最终通知、环绕通知
-
Aspect(切面):是切入点和通知(引介)的结合
-
Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程。spring采用动态代理织 入,而AspectJ采用编译期织入和类装载期织入
-
@Before:这种拦截器先执行拦截代码,再执行目标代码。如果拦截器抛异常,那么目标代码就不执行了;
-
@After:这种拦截器先执行目标代码,再执行拦截器代码。无论目标代码是否抛异常,拦截器代码都会执行;
-
@AfterReturning:和@After不同的是,只有当目标代码正常返回时,才执行拦截器代码;
-
@AfterThrowing:和@After不同的是,只有当目标代码抛出了异常时,才执行拦截器代码;
添加maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
添加切面配置
config/AopConfig.java
@Configuration
@ComponentScan("com.lagou.aop")
@EnableAspectJAutoProxy
public class AopConfig {
}
添加切面类
aop/LogAop.java
@Component
@Aspect
public class LogAop {
@Pointcut("execution(* com.lagou.controller.UserController.*(..))")
public void log(){}
@Before("log()")
public void before() {
System.out.println("[before] execute");
}
@AfterReturning(value = "log()",returning = "retVal")
public void afterReturning(Object retVal) {
System.out.println("[AfterReturning] retVal:"+retVal);
}
@AfterThrowing(value = "log()",throwing = "ex")
public void afterThrowing(Exception ex) {
System.out.println("[AfterThrowing] execute:"+ex);
}
@After("log()")
public void after() {
System.out.println("[After] finally execute");
}
@Around("log()")
public Object around(ProceedingJoinPoint pjb) throws Throwable {
Object processed=null;
try {
System.out.println("[Around] 前置");
//切点方法执行
processed = pjb.proceed();
System.out.println("[Around] 后置");
return processed;
} catch(Exception e) {
System.out.println("[Around] 异常");
return processed;
} finally {
System.out.println("[Around] 最终");
}
}
}
[Around] 前置
[before] execute
[AfterReturning] retVal:[]
[After] finally execute
[Around] 后置
[Around] 最终
执行顺序
Before -->AfterReturning(有异常时AfterThrowing) -->After
Advice 参数
ProceedingJoinPoint
ProceedingJoinPoint 的父类 JoinPoint
The
JoinPointinterface provides a number of useful methods such as
getArgs()(returns the method arguments),
getThis()(returns the proxy object),
getTarget()(returns the target object),
getSignature()(returns a description of the method that is being advised)
toString()(prints a useful description of the method being advised). Please do consult the Javadocs for full details.
参数传递
@Pointcut("execution(* com.lagou.controller.UserController.getUserById(..)) && args(id,..))")
public void log(Integer id) {
}
@Before(value = "log(id)")
public void before(Integer id) {
System.out.println("[before] execute" + id);
}