Spring知识点总结篇2 AOP

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知识点总结篇2 AOP

Spring AOP 实现

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

Spring知识点总结篇2 AOP
  • 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;
    }
}

Original: https://www.cnblogs.com/spring-ioc/p/16558155.html
Author: 你问人生何
Title: Spring知识点总结篇2 AOP

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/574233/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • SpringBoot笔记(三):静态资源和动态模板

    SSM中的静态资源配置 Spring xml中通过节点配置静态资源: 还有一种简化的配置风格: 除了xml配置还可以通过java代码来配置静态资源: @Configuration …

    Java 2023年6月7日
    061
  • SpringMvc @Validated注解执行原理

    @Validated和@Valid对比 Spring Validation验证框架对参数的验证机制提供了@Validated(Spring’s JSR-303规范,是标…

    Java 2023年5月30日
    073
  • ElasticSearch增加索引字段

    PUT xxx_index-000009/_mapping/_doc?include_type_name=true { “properties”:{ &#8…

    Java 2023年6月13日
    068
  • ArrayList源码分析

    ArrayList源码分析 默认大小 // 根据传入的初始化大小创建对应的数组大小 public ArrayList(int initialCapacity) { if (init…

    Java 2023年6月16日
    072
  • Java项目代码是如何分层的

    1、背景 说起应用分层,大部分人都会认为这个不是很简单嘛 就controller,service, mapper三层。看起来简单,很多人其实并没有把他们职责划分开,在很多代码中,c…

    Java 2023年6月5日
    083
  • 微服务与领域驱动设计,架构实践总结

    怎样的架构才能配得上造到飞起的变化? 一、软件复杂性 1、复杂原因 如果软件系统存在持续的迭代周期,那么其中业务、技术、架构的复杂性都会直线拉升,其相应的开发难度也会提高,可以用一…

    Java 2023年6月15日
    064
  • 这个开源组织里的项目都是精品

    前言 在开源中国里,不知道大家有没有留意到一个Java开源组织——Dromara? 这个组织是由Apache ShenYu(前身是Soul网关)的作者创立,多位Java开源作者参与…

    Java 2023年6月8日
    070
  • 教你win7系统手动导入注册表获取管理员权限

    想必大家都遇到过win7系统手动导入注册表获取管理员权限的问题吧,大多数朋友还不知道怎么处理固然处理起来也不难,然而还是有一些小伙伴不明白win7系统手动导入注册表获取管理员权限应…

    Java 2023年5月30日
    077
  • 使用URL快捷方式提高效率

    阅文时长 | 0.9分钟字数统计 | 1453.6字符主要内容 | 1、引言&背景 2、URL格式基本格式介绍 3、附录:Hotkey详细参数 4、拓展:收藏夹中的URL格…

    Java 2023年6月5日
    066
  • 【Git 系列】基础知识全集

    Git 是一种分布式版本控制系统,它可以不受网络连接的限制,加上其它众多优点,目前已经成为程序开发人员做项目版本管理时的首选,非开发人员也可以用 Git 来做自己的文档版本管理工具…

    Java 2023年6月5日
    061
  • oralce 11g 数据库及客户端client等的下载安装

    oralce 11g 数据库及客户端client等的下载安装 下载地址:https://www.oracle.com/cn/database/technologies/micros…

    Java 2023年6月13日
    077
  • 单核CPU、多个CPU(路)、超线程技术、多核CPU(物理核、逻辑核)

    1.单核CPU 路、CPU、物理核、逻辑核和超线程概念 一个服务器主板可以插多个CPU称为多路,一个CPU可以有多个物理核。如果开启了超线程,一个物理核可以分成n个逻辑核(一般是2…

    Java 2023年5月30日
    073
  • Java 异步实现的几种方式

    jdk并发包里的Future代表了未来的某个结果,当我们向线程池中提交任务的时候会返回该对象,可以通过future获得执行的结果,但是jdk1.8之前的Future有点鸡肋,并不能…

    Java 2023年5月29日
    066
  • java 获取网页写入本地文件来解决让一个js事件

    依赖 org.apache.httpcomponents httpmime 4.5.2 org.apache.poi poi 3.14 调用 public static void …

    Java 2023年6月9日
    063
  • leetcode 226. Invert Binary Tree 翻转二叉树(简单)

    一、题目大意 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root = [4,2,7,1,3,6,9]输出:[4,7,2,9,6,3,1…

    Java 2023年6月14日
    075
  • 机器学习常用指标

    一、机器学习常用指标 对于一个分类任务,我们预测情况大致如下面混淆矩阵所示: 预测为正样本预测为负样本 标签为正样本 TP FN 标签为负样本 FP TN 1、accuracy a…

    Java 2023年6月15日
    065
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球