AOP术语
1、连接点:类里面哪些方法可以被增强,这些方法被称为连接点
2、切入点:实际被真正增强的方法,称为切入点
3、通知(增强):实际增强的逻辑部分称为通知(增强),通知有多种类型(前置,后置,环绕,异常,最终通知)
4、切面:是一个动作,把通知应用到切入点的过程。
AOP操作(准备工作)
1. Spring框架一般是基于AspectJ实现AOP操作的
2.实现aop操作方式:
- 基于xml配置文件实现
- 基于注解方式实现
3.AOP依赖引入
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
4.切入点表达式
- 作用:知道对哪个类里面的哪个方法进行增强
- 语法结构:execution(【权限修饰符】【返回类型】【类全路径】【方法名称】(【参数列表】))
- 例子1:对com.che.dao.Book类里面的add方法进行增强
- execution(* com.che.dao.Book.add(…))
- 例子2:对com.che.dao.Book类里面的所有方法进行增强
- execution(* com.che.dao.Book.*(…))
- 例子3:对com.che.dao包下面所有类,类里面所有方法进行增强
- execution(* com.che.dao..(…))
- 例子1:对com.che.dao.Book类里面的add方法进行增强
AOP操作(Aspect基于注解形式)
-
创建被增强的类
public class User { public void add(){ System.out.println("user..............add"); } }
-
创建增强的类(编写增强的逻辑)
public class UserProxy { public void before(){ System.out.println("before........."); } public void after(){ System.out.println("after........."); } public void afterReturning(){ System.out.println("afterReturning........."); } public void afterThrowing(){ System.out.println("afterThrowing........."); } public void around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("环绕之前.............."); //被增强的方法执行 joinPoint.proceed(); System.out.println("环绕之后.............."); } }
-
进行通知的配置
1). 在spring配置文件中,开启注解扫描<!--开启注解扫描--> <context:component-scan base-package="com.che.spring.aop"></context:component-scan>
2).使用注解创建User和UserProxy对象
@Component public class User { public void add(){ System.out.println("user..............add"); } }
@Component public class UserProxy { public void before(){ System.out.println("before........."); } public void after(){ System.out.println("after........."); } public void afterReturning(){ System.out.println("afterReturning........."); } public void afterThrowing(){ System.out.println("afterThrowing........."); } public void around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("环绕之前.............."); //被增强的方法执行 joinPoint.proceed(); System.out.println("环绕之后.............."); } }
3).在增强的类上添加注解@Aspect
@Component @Aspect //生成代理对象 public class UserProxy {
4).在spring配置文件中开启生成代理对象
<!--开启Aspect生成代理对象--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
-
在增强的类上UserProxy配置不同类型的通知
//前置通知 @Before(value = "execution(* com.che.spring.aop.aopanno.User.add(..))") public void before(){ System.out.println("before........."); } //最终通知 无论方法有没有异常都会执行 @After(value = "execution(* com.che.spring.aop.aopanno.User.add(..))") public void after(){ System.out.println("after........."); } //后置通知(返回通知) 如果方法有异常,他就不会执行 @After(value = "execution(* com.che.spring.aop.aopanno.User.add(..))") public void afterReturning(){ System.out.println("afterReturning........."); } //异常通知 当方法出现异常时才会执行 @AfterThrowing(value = "execution(* com.che.spring.aop.aopanno.User.add(..))") public void afterThrowing(){ System.out.println("afterThrowing........."); } //环绕通知 @Around(value = "execution(* com.che.spring.aop.aopanno.User.add(..))") public void around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("环绕之前.............."); //被增强的方法执行 joinPoint.proceed(); System.out.println("环绕之后.............."); }
-
相同切入点抽取
//相同切入点抽取 @Pointcut(value = "execution(* com.che.spring.aop.aopanno.User.add(..))") public void pointDemo(){ } //前置通知 @Before(value = "pointDemo()") public void before(){ System.out.println("before........."); }
-
有多个增强类对同一个方法进行增强,设置增强类优先级
1).在多个增强类上添加@Order注解,数字越小,优先级越高@Component @Aspect //生成代理对象 @Order(3) //如果有多个增强的类,可设置优先级进行增强,数字越低,优先级越高 public class UserProxy { }
-
完全使用注解开发
1).创建配置类,不需要创建xml配置文件//这个类的配置相当于bean12.xml @Configuration @ComponentScan(basePackages= {"com.che.spring.aop"}) @EnableAspectJAutoProxy(proxyTargetClass = true) //相当于xml配置的 <aop:aspectj-autoproxy></aop:aspectj-autoproxy> public class ConfigAop { }
AOP操作(Aspect基于XML形式)
- 创建两个类,增强类和被增强类
//增强类 public class BookProxy { public void before(){ System.out.println("before..................."); } }
//被增强类 public class Book { public void buy(){ System.out.println("book...........buy"); } }
- 在spring配置文件创建两个类对象
<!-- 创建对象--> <bean class="com.che.spring.aop.aopxml.Book" id="book"></bean> <bean class="com.che.spring.aop.aopxml.BookProxy" id="bookProxy"></bean>
- 在spring配置文件中配置切入点,切面,通知等
<!--配置aop增强--> <aop:config> <!--切入点--> <aop:pointcut id="point" expression="execution(* com.che.spring.aop.aopxml.Book.*(..))"/> <!--配置切面--> <aop:aspect ref="bookProxy"> <!--配置前置通知--> <aop:before method="before" pointcut-ref="point"></aop:before> </aop:aspect> </aop:config>