一、什么是AOP?

Aspect Oriented Programming ,即面向切面编程。

  • AOP是对面向对象编程的一个补充。
  • 它的目的是将复杂的需求分解为不同的切面,将散布在系统中的公共功能集中解决。
  • 它的实际含义是在运行时将代码切入到类的指定方法、指定位置上,将不同方法的同一个位置抽象为一个切面对象,并对该对象进行编程。

下面是AOP的一个示意图

二、AOP的优点和一些概念

1、AOP的优点
  • 降低模块之间的耦合度
  • 使系统更容易扩展
  • 更好的代码复用
  • 非业务代码更加集中,不分散,便于统一管理
  • 业务代码更加简洁纯粹,不掺杂其他的代码的影响
2、AOP中出现的一些概念
  • 切面:横切关注点,被模块化的抽象对象
  • 通知:切面对象完成的工作(非业务代码)
  • 目标:被通知的对象(即被横切的对象)
  • 代理:切面、通知、目标混合之后的对象
  • 连接点:通知要插入业务代码的具体位置(如Spring实现中的JoinPoint)
  • 切点:AOP通过切点定位到连接点

三、使用动态代理实现AOP

1、添加依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.0.11.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.0.11.RELEASE</version>
</dependency>
2、创建一个计算器接口Cal,定义四个方法

动态代理的类的方法应当都由接口来实现,这样才方便使用动态代理对象执行方法

3、创建接口的实现类CalImpl

高耦合的写法,每次打印日志都要手动完成:

4、使用动态代理进行优化

上方代码中,日志信息和业务逻辑的耦合性很高,不利于代码的维护。使用AOP可以进行优化,我们可以使用动态代理实现AOP:

给业务代码找一个代理,打印日志信息的工作交给代理来做。这样的话业务代码就只需要关注自身业务即可。

(1)去掉手动输出的日志信息



(2).代理辅助类的编写和使用(动态代理的核心)

我们创建的并不是所谓的代理类,而是一个可以帮助我们返回代理对象的辅助类,这个辅助类有两个功能

  1. 接收委托对象并依次返回代理对象
  2. 处理代理对象调用方法的过程



    值得注意的是:
  • 注意别忘了给委托对象赋值的那一步
  • 创建代理动态代理对象时传入的方法保证了代理类拥有原类的全部功能
  • 调用代理对象的方法时会自动调用invoke方法

    (3)测试

四、使用Spring实现AOP

动态代理实现AOP比较复杂,不易理解。Spring框架对AOP进行了封装,使用Spring框架可以用面向对象的思想实现AOP。Spring框架中不需要创建辅助类,只需要创建一个切面对象,将所有的非业务代码在切面对象中完成即可(但实际上Spring框架底层依然会根据切面类和代理类来生成代理对象。)

1、添加依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.0.11.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.0.11.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.11.RELEASE</version>
</dependency>
2、创建一个计算器接口Cal,定义四个方法

当使用Spring实现时,这一步非必须!直接在实体类里面定义方法也可

3、定义实体类,实现方法

注意需要加上Component注解把他交给IoC

4、创建切面类



类定义处的两个注解

  • @Aspect表示该类是一个切面类
  • @Component将该类的对象注入到IoC容器(切面类和实体类都需要加上这个注解)

方法处的注解

  • @Before表示方法执行的具体位置和时机是方法开始时

  • @After类似Before,不过位置是方法的最后

  • @AfterReturning在下文有作解释

  • @AfterThrowing在下文有作解释

5、在spring.xml中进行配置

  • context:component-scan指扫描com.pedro包中的所有类,如果该类同时添加了component注解,则将该类扫描IoC容器中。即IoC管理它的对象
  • aop:aspectj-autoproxy让Spring容器结合切面类和目标类自动生成代理对象
6、使用



用代理对象调用方法就会自动执行它本身的方法和切面类中的非业务代码

为什么类名首字母要小写?

当使用注解配置bean时,默认id(别名)就是首字母改为小写的类名。若想修改,就在实体类的注解处加上自定义的名字即可。如@Component("test"),这样的话在getBean的时候就可以使用自定义的别名了,即xx.getBean("test")

7、两个特殊的After注解

(1)AfterReturning

用于在获取返回值后执行一段非业务代码

注:因为有两个参数,这里的value标签名被标出,而上面的before、after等注解只有一个参数,所以省略了value

结合上面的其他注解,会输出:

div方法的参数是[6,2]
div方法执行完毕
div方法的结果是3

(2)AfterThrowing

切面类的AfterThrowing注解,用于在抛出异常后执行一段非业务代码



结合上面的其他注解,会输出:

div方法的参数是[6,0]
div方法执行完毕
div方法抛出的异常:java.lang.ArithmeticException: / by zero

2021.4.3

Java中的面向切面编程(AOP)的更多相关文章

  1. [译]如何在ASP.NET Core中实现面向切面编程(AOP)

    原文地址:ASPECT ORIENTED PROGRAMMING USING PROXIES IN ASP.NET CORE 原文作者:ZANID HAYTAM 译文地址:如何在ASP.NET Cor ...

  2. Spring中的面向切面编程(AOP)简介

    一.什么是AOP AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面 ...

  3. 04 Spring:01.Spring框架简介&&02.程序间耦合&&03.Spring的 IOC 和 DI&&08.面向切面编程 AOP&&10.Spring中事务控制

    spring共四天 第一天:spring框架的概述以及spring中基于XML的IOC配置 第二天:spring中基于注解的IOC和ioc的案例 第三天:spring中的aop和基于XML以及注解的A ...

  4. Spring学习手札(二)面向切面编程AOP

    AOP理解 Aspect Oriented Program面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. 但是,这种说法有些片面,因为在软件工程中,AOP的价值体现的并 ...

  5. Spring学习笔记:面向切面编程AOP(Aspect Oriented Programming)

    一.面向切面编程AOP 目标:让我们可以“专心做事”,避免繁杂重复的功能编码 原理:将复杂的需求分解出不同方面,将公共功能集中解决 *****所谓面向切面编程,是一种通过预编译方式和运行期动态代理实现 ...

  6. Spring框架学习笔记(2)——面向切面编程AOP

    介绍 概念 面向切面编程AOP与面向对象编程OOP有所不同,AOP不是对OOP的替换,而是对OOP的一种补充,AOP增强了OOP. 假设我们有几个业务代码,都调用了某个方法,按照OOP的思想,我们就会 ...

  7. Spring之控制反转——IoC、面向切面编程——AOP

      控制反转——IoC 提出IoC的目的 为了解决对象之间的耦合度过高的问题,提出了IoC理论,用来实现对象之间的解耦. 什么是IoC IoC是Inversion of Control的缩写,译为控制 ...

  8. Spring框架系列(4) - 深入浅出Spring核心之面向切面编程(AOP)

    在Spring基础 - Spring简单例子引入Spring的核心中向你展示了AOP的基础含义,同时以此发散了一些AOP相关知识点; 本节将在此基础上进一步解读AOP的含义以及AOP的使用方式.@pd ...

  9. 【串线篇】面向切面编程AOP

    面向切面编程AOP 描述:将某段代码“动态”的切入到“指定方法”的“指定位置”进行运行的一种编程方式 (其底层就是Java的动态代理)spring对其做了简化书写 场景: 1).AOP加日志保存到数据 ...

随机推荐

  1. Flow All In One

    Flow All In One Flow is a static type checker for JavaScript https://github.com/facebook/flow https: ...

  2. 视屏剪辑软件 & free video editor

    视屏剪辑软件 & free video editor purpose add animation keyframe to tutorials video vlog demos tutorial ...

  3. how to install zoom meeting app in macOS

    how to install zoom meeting app in macOS https://support.zoom.us/hc/zh-cn/articles/203020795-如何在Mac上 ...

  4. .gitignore规则不生效

    .gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的. 解决方法就是先把本地缓存删除(改变成未track状态),然后再提交 ...

  5. 在gradle中构建java项目

    目录 简介 构建java项目的两大插件 管理依赖 编译代码 管理resource 打包和发布 生成javadoc 简介 之前的文章我们讲到了gradle的基本使用,使用gradle的最终目的就是为了构 ...

  6. 07.k近邻算法kNN

    1.将数据分为测试数据和预测数据 2.数据分为data和target,data是矩阵,target是向量 3.将每条data(向量)绘制在坐标系中,就得到了一系列的点 4.根据每条data的targe ...

  7. 11_MySQL如何让数据分页显示

    -- 数据分页 SELECT empno,sal FROM t_emp LIMIT 5;

  8. [Python学习笔记]组织文件

    shutil 模块 shutil 模块可以让我们很方便的在Python程序中复制.移动.改名和删除文件. 复制文件和文件夹 使用shutil.copy()来复制文件,该函数含两个参数,均为字符串格式的 ...

  9. Docker 镜像加速教程

    原文链接:https://fuckcloudnative.io/posts/docker-registry-proxy/ 在使用 Docker 和 Kubernetes 时,我们经常需要访问 gcr. ...

  10. Java基础语法:运算符

    Java 运算符(operator)根据功能分类: 算术运算符:+,-,*,/,%,++,-- 赋值运算符:= 关系运算符:>,<,>=,<=,==,!=,instanceof ...