什么是AOP技术
AOP 是一种面向切面的编程思想。面向切面编程是将程序抽象成各个切面,即解刨对象的内部,将那些影响了多个类的公共行为抽取到一个可重用模块里,减少系统的重复代码,降低模块间的耦合度,增强代码的可操作性和可维护性。
AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理、增强处理。
通俗易懂aop是在我们的目标方法之前和之后处理的操作,应用场景在于:日志打印、事务实现、权限控制等
AOP 可以解决我们程序上的代码冗余问题
AOP技术底层原理
AOP 常用术语
1、连接点:该类中哪些方法需要被增强,这些方法就可以称作连接点
2、通知(增强)
(1)实际增强的逻辑部分称为通知(增强)
(2)通知有多种类型
- 前置通知:在方法执行前执行
- 后置通知:在方法执行后执行
- 环绕通知:在方法执行前后都执行
- 异常通知:增强类方法出现异常会通知
- 最终通知:不管有没有异常都会执行
3、切入点:实际被增强的方法,称为切入点
切入点表达式
1、切入点表达式作用:知道对哪个类里面的哪个方法进行增强
2、语法结构: execution([权限修饰符] [返回类型] [类全路径] )
举例 1:对 com.fblinux.dao.BookDao 类里面的 add 进行增强 execution(* com.fblinux.dao.BookDao.add(..))
举例 2:对 com.fblinux.dao.BookDao 类里面的所有的方法进行增强 execution(* com.fblinux.dao.BookDao.* (..))
举例 3:对 com.fblinux.dao 包里面所有类,类里面所有方法进行增强 execution(* com.fblinux.dao.. (..))
SpringBoot AOP 实现
AOP 环境准备
1.Spring框架一般都是基于AspectJ实现AOP操作
什么是AspectJ?
AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法,它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件,AspectJ不是Spring组成部分,独立AOP框架,一般把AspectJ和Spring框架一起使用,进行AOP操作.
配置AOP之前在需要在springboot工程目录中引入aspectj包
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.6</version> </dependency>
SpringBoot配置
目录结构:
测试接口:
@Controller public class HelloController { @GetMapping("/hello") //用户请求的接口 @ResponseBody //代表将字符串作为响应的内容直接返回给客户端 public String hello(String name){ return "hello ," + name; } }
配置代码:
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.context.annotation.Configuration; @Configuration @Aspect public class AopConfig { /** * 前置通知 */ @Before("execution(* com.fblinux.aop.controller.HelloController.hello(..));") public void before() { System.out.println("前置通知..."); } /** * 后置通知 */ @After("execution(* com.fblinux.aop.controller.HelloController.hello(..));") public void after() { System.out.println("后通知..."); } /** * 环绕通知 */ @Around(value = "execution(* com.fblinux.aop.controller.HelloController.hello(..));") public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("环绕通知..."); System.out.println("目标方法之前开始执行..."); Object result = proceedingJoinPoint.proceed(); System.out.println("目标方法之后开始执行..."); return result; } //@AfterReturning表达后置通知/返回通知,表达方法返回结果之后执行 @AfterReturning(value = "execution(* com.fblinux.aop.controller.HelloController.hello(..));") public void afterReturning() { System.out.println("afterReturning"); } //@AfterThrowing表达异常通知 @AfterThrowing(value = "execution(* com.fblinux.aop.controller.HelloController.hello(..));") public void afterThrowing() { System.out.println("afterThrowing"); } }
结果验证:
命令行访问接口:
curl http://127.0.0.1:8080/hello?name=fblinux
@Pointcut(value = "execution(* com.fblinux.aop.controller.HelloController.hello(..));") public void pointdemo(){ } /** * 前置通知 */ @Before(value = "pointdemo()") public void before() { System.out.println("前置通知..."); }
增强优先级设计
有多个增强类多同一个方法进行增强,设置增强类优先级
在增强类上面添加注解 @Order(数字类型值),数字类型值越小优先级越高
spring框架使用那种代理模式
Spring aop底层基于代理模式封装
如果我们被代理类没有实现接口的情况下,则使用cglib动态代理
如果我们被代理类有实现接口的情况下,则使用jdk动态代理
转载请注明:西门飞冰的博客 » Spring—AOP面向切面编程