你好,欢迎来到你问人生何的博客园啊

Spring知识点总结篇2 AOP

AOP篇总结

AOP 是什么?

AOP 即面向切面编程,简单地说就是将代码中重复的部分抽取出来,在需要执行的时候使用动态代理技术,在不修改[源码]()的基础上对方法进行增强。

这种在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程

Spring 根据类是否实现接口来判断动态代理方式,如果实现接口会使用 JDK 的动态代理,核心是 InvocationHandler 接口和 Proxy 类,如果没有实现接口会使用 CGLib 动态代理,CGLib 是在运行时动态生成某个类的子类,如果某个类被标记为 final,不能使用 CGLib 。

常用场景包括权限认证、自动缓存、错误处理、日志、调试和事务等。

 

 

 

 

如何理解AOP中的连接点(Joinpoint)、切点(Pointcut)、增强(Advice)、引介(Introduction)、织入(Weaving)、切面(Aspect)这些概念?

 a. 连接点(Joinpoint):程序执行的某个特定位置(如:某个方法调用前、调用后,方法抛出异常后)。一个类或一段程序代码拥有一些具有边界性质的特定点,这些代码中的特定点就是连接点。Spring仅支持方法的连接点。
在一个类中那些可以被增强的方法叫做连接点
 
b. 切点(Pointcut):如果连接点相当于数据中的记录,那么切点相当于查询条件,一个切点可以匹配多个连接点。Spring AOP的规则解析引擎负责解析切点所设定的查询条件,找到对应的连接点。
实际真正被增强的方法叫做切入点
 
c. 增强(Advice):增强是织入到目标类连接点上的一段程序代码。Spring提供的增强接口都是带方位名的,如:BeforeAdvice、AfterReturningAdvice、ThrowsAdvice等。
1)实际被增强的逻辑部分叫通知
(2)通知有多种类型
1 前置通知
2 后置通知
在方法前后执行
3 环绕通知
在方法前后都做执行
4 异常通知
出现异常再执行
5 最终通知
finally 无论是否异常都会通知
 
 
d切面
是动作 把通知应用到切入点的过程
例如把权限判断加到登陆页面的过程
 
f通知
通知是个在方法执行前或执行后要做的动作,实际上是程序执行时要通过SpringAOP框架触发的代码段。
Spring切面可以应用五种类型的通知:
before:前置通知,在一个方法执行前被调用。
after: 在方法执行之后调用的通知,无论方法执行是否成功。
after-returning: 仅当方法成功完成后执行的通知。
after-throwing: 在方法抛出异常退出时执行的通知。
around: 在方法执行之前和之后调用的通知
 
 
 
 

AOP 的过程?

Spring AOP 由 BeanPostProcessor 后置处理器开始,这个后置处理器可以监听容器触发的 Bean 生命周期事件,向容器注册后置处理器以后,容器中管理的 Bean 就具备了接收 IoC 容器回调事件的能力。BeanPostProcessor 的调用发生在 Spring IoC 容器完成 Bean 实例对象的创建和属性的依赖注入后,为 Bean 对象添加后置处理器的入口是 initializeBean 方法。

Spring 中 JDK 动态代理通过 JdkDynamicAopProxy 调用 Proxy 的 newInstance 方法来生成代理类,JdkDynamicAopProxy 也实现了 InvocationHandler 接口,invoke 方法的具体逻辑是先获取应用到此方法上的拦截器链,如果有拦截器则创建 MethodInvocation 并调用其 proceed 方法,否则直接反射调用目标方法。因此 Spring AOP 对目标对象的增强是通过拦截器实现的。

 

 

Spring AOP有哪些通知类型,它们的执行顺序是怎样的?

 

​ 在基于Spring AOP编程的过程中,基于AspectJ框架标准,spring中定义了五种类型的通知,它们分别是:

  • 前置通知 (@Before) 。
  • 返回通知 (@AfterReturning) 。
  • 异常通知 (@AfterThrowing) 。
  • 后置通知 (@After)。
  • 环绕通知 (@Around) :(优先级最高)

通知执行顺序

​ 将上面的所有通知类型写入同一个切面中,它的执行顺序为:

在增强类中 在作为通知的方法上添加通知类型注解 并且使用切入点表达式来配置内容
 
基于AspectJ 注解方式 实现五种通知类型配置
//增强类
//在增强类中创建方法让不同的方法代表不同的通知类型

//通过注解来创建类的对象
@Component
@Aspect//生成代理对象
public class UserProxy {
//  1  前置通知 在add()方法之前做一个before()方法 before注解表示作为前置通知 具体到哪个类那个方法作为通知(加强)
    @Before(value = "execution(* com.qijie.AOP.User.add(..))")//切入点表达式
    public void before(){
        System.out.println("before......");
    }




//    2最终通知 在方法执行之后执行 不管调用是否有一场 他最后都会输出
    @After(value = "execution(* com.qijie.AOP.User.add(..))")//切入点表达式
    public  void after(){
        System.out.println("after......");
    }


// 后置通知在返回值之后执行  当有异常情况下就不会输出
    @AfterReturning(value = "execution(* com.qijie.AOP.User.add(..))")//切入点表达式
    public  void afterreturnning(){
        System.out.println("afterReturning......");
    }



//异常通知 如果add()有异常才会执行
    @AfterThrowing(value = "execution(* com.qijie.AOP.User.add(..))")//切入点表达式
    public  void afterThrowing(){
        System.out.println("afterThrowing......");
    }



//    环绕通知 在被增强方法前后都执行  类似jdk动态代理实现 invotionHandler接口实现
    @Around(value = "execution(* com.qijie.AOP.User.add(..))")//切入点表达式
    public  void Around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("Around 环绕之前......");
//        被增强的方法执行
      proceedingJoinPoint.proceed();//执行被增强的方法
        System.out.println("Around 环绕之后......");
    }


}

 

 

 

 

AOP 的两种实现方式

AOP 采用了两种实现方式:静态织入(AspectJ 实现)和动态代理(Spring AOP实现)

AspectJ

AspectJ 是一个采用Java 实现的AOP框架,它能够对代码进行编译(一般在编译期进行),让代码具有AspectJ 的 AOP 功能,AspectJ 是目前实现 AOP 框架中最成熟,功能最丰富的语言。ApectJ 主要采用的是编译期静态织入的方式。在这个期间使用 AspectJ 的 acj 编译器(类似 javac)把 aspect 类编译成 class 字节码后,在 java 目标类编译时织入,即先编译 aspect 类再编译目标类。

Spring AOP 实现

Spring AOP 是通过动态代理技术实现的,而动态代理是基于反射设计的。Spring AOP 采用了两种混合的实现方式:JDK 动态代理和 CGLib 动态代理,分别来理解一下

  • JDK动态代理:Spring AOP的首选方法。 每当目标对象实现一个接口时,就会使用JDK动态代理。目标对象必须实现接口
  • CGLIB代理:如果目标对象没有实现接口,则可以使用CGLIB代理。

 

@AspectJ 支持

为了在Spring 配置中使用@AspectJ ,你需要启用Spring支持,以根据@AspectJ切面配置Spring AOP,并配置自动代理。自动代理意味着,Spring 会根据自动代理为 Bean 生成代理来拦截方法的调用,并确保根据需要执行拦截。

 

 

Spring AOP 和 AspectJ AOP 有什么区别?

Spring AOP 属于运行时增强,而 AspectJ 是编译时增强。 Spring AOP 基于代理(Proxying),而 AspectJ 基于字节码操作(Bytecode Manipulation)。

Spring AOP 已经集成了 AspectJ ,AspectJ 应该算的上是 Java 生态系统中最完整的 AOP 框架了。AspectJ 相比于 Spring AOP 功能更加强大,但是 Spring AOP 相对来说更简单,

如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择 AspectJ ,它比 Spring AOP 快很多。

 

 

 

多个切面的执行顺序如何控制?

1、通常使用@Order 注解直接定义切面顺序

// 值越小优先级越高
@Order(3)
@Component
@Aspect
public class LoggingAspect implements Ordered {

2、实现Ordered 接口重写 getOrder 方法。

@Component
@Aspect
public class LoggingAspect implements Ordered {

    // ....

    @Override
    public int getOrder() {
        // 返回值越小优先级越高
        return 1;
    }
}

 

 

 

 
 
posted @   你问人生何  阅读(69)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?

本站勉强运行 1945 天 23 小时 20 分 01 秒

点击右上角即可分享
微信分享提示