1、作用
不改变某方法的源码,给这个方法增添功能。
2、概念
(1)切入点:被增强的方法。
切入点表达式:
execution (public * com.ljb.service.impl….(…))
execution(权限修饰符,返回值类型,类全路径,方法名称,参数列表)
1.execution:指示符,execution是最常用的指示符,用于匹配方法执行的连接点。
2.public:访问修饰符,该参数可选。
3.第一个*号:返回值类型,*号表示所有的类型,即通配符。
4.包名:需要拦截的包名,后面的两个点表示当前包和当前包的所有子包,即例子中的com. ljb.service.impl包和该包的子孙包下所有类。
5.第二个*号:类名,*号表示所有的类。
*(…):方法名,*号表示所有方法,括号里面表示方法的参数,两个点表示任何参数,可有可无。
(2)通知(增强):增添的功能。
通知有五种类型:
1、前通知:方法执行之前,method:增强执行的方法
2、后通知:方法执行之后,又称最终通知,无论如何都执行
3、返回后通知:成功返回后,有异常时不执行
4、异常通知:发生异常后,只有异常抛出时才执行,不能try…catch异常
5、环绕通知:在方法的执行前后进行一些增强,在方法的执行前后进行一些增强 =前通知+返回后通知
3、实现(SpringBoot项目)
(1)新建一个切面类,添加类注解@Aspect和@Component。
@Aspect
@Component
public class Aspect1 {
}
(2)可以直接增强某一个方法,如:
@Aspect
@Component
public class Aspect1 {
@Before(value = "execution(* xlh.zy.com.Zyf.add())")
public void before(){
System.out.println("Before......");
}
}
在执行Zyf类的add()方法前会先打印"Before…"。
(3)也可以先定义切点,在切点中指定需要加强的一个或一些方法,如:
@Aspect
@Component
public class Aspect1 {
//@2:定义了一个切入点,可以匹配Service1中所有方法
@Pointcut("execution(* com.javacode2018.aop.demo9.test1.Service1.*(..))")
public void pointcut1() {
}
//@3:定义了一个前置通知,这个通知对刚刚上面我们定义的切入点中的所有方法有效
@Before(value = "pointcut1()")
public void before(JoinPoint joinPoint) {
//输出连接点的信息
System.out.println("前置通知," + joinPoint);
}
//@4:定义了一个异常通知,这个通知对刚刚上面我们定义的切入点中的所有方法有效
@AfterThrowing(value = "pointcut1()", throwing = "e")
public void afterThrowing(JoinPoint joinPoint, Exception e) {
//发生异常之后输出异常信息
System.out.println(joinPoint + ",发生异常:" + e.getMessage());
}
}
@1:类上使用@Aspect标注
@2:通过@Pointcut注解标注在方法上面,用来定义切入点
@3:使用@Before标注在方法上面,定义了一个前置通知,通过value引用了上面已经定义的切入点,表示这个通知会对Service1中的所有方法生效,在通知中可以通过这个类名.方法名()引用@Pointcut定义的切入点,表示这个通知对这些切入点有效,若@Before和@Pointcut在一个类的时候,直接通过方法名()引用当前类中定义的切入点
@4:这个使用@AfterThrowing定义了一个异常通知,也是对通过value引用了上面已经定义的切入点,表示这个通知会对Service1中的所有方法生效,若Service1中的方法抛出了Exception类型的异常,都会回调afterThrowing方法。
.
.
.
.
.
@Aspect标注的类上,这个类中,可以通过通过@Pointcut来定义切入点,可以通过@Before、@Around、@After、@AfterRunning、@AfterThrowing标注在方法上来定义通知,定义好了之后,将@Aspect标注的这个类交给AspectJProxyFactory来解析生成Advisor链,进而结合目标对象一起来生成代理对象,大家可以去看一下源码,比较简单,这里就不多解释了。
本文的重点在@Aspect标注的类上,@Aspect中有2个关键点比较重要
@Pointcut:标注在方法上,用来定义切入点,有11种用法,本文主要讲解这11种用法。
@Aspect类中定义通知:可以通过@Before、@Around、@After、@AfterRunning、@AfterThrowing标注在方法上来定义通知,这个下一篇介绍。
详见https://zhuanlan.zhihu.com/p/153317556