11.1、什么是AOP

AOP(Aspect Oriented Programming) 要为: 面向切面编程, 通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP是延续, 是软件开发中的一个热点, 也是Spring框架中的一个重要内容, 是函数式编程的一种衍生泛型。利用AOP可以对业务逻辑的各个部分进行隔离, 从而使得业务逻辑各部分之间的耦合度降低, 提高程序的可重用性, 同时提高开发的效率
![image.png](https://img-blog.csdnimg.cn/img_convert/eb7828db5d6da070a8da77c6711ac556.png#clientId=u2755809b-38bf-4&from=paste&height=468&id=u310a1feb&margin=[object Object]&name=image.png&originHeight=531&originWidth=920&originalType=binary&ratio=1&size=396729&status=done&style=none&taskId=u1dfecb83-9580-4f1d-a845-e335098d2bf&width=811)

11.2、Aop在Spring中的作用

提供声明式事务; 允许用户自定义切面
①横切关注点 : 跨越应用程序多个模块的方法或功能。即, 与我们业务逻辑无关的, 但是我们需要关注的部分, 就是横切关注点。如日志、安全、缓存、事务等等
②切面(ASPECT) : 横切关注点被模块化的特殊对象。即, 他是一个类
③通知(Advice) : 切面必须要完成的工作, 即, 他是类中的一个方法
④目标(Target) : 被通知的对象。即, 一个接口或者方法
⑤代理(Proxy) : 向目标对象应用通知后创建的对象。
⑥切入点(PointCut) : 切面通知执行的"地点"的定义。
⑦连接点(JointPoint) : 与切入点匹配的执行点。

![image.png](https://img-blog.csdnimg.cn/img_convert/074be86e818bae9f83eda689baf40b21.png#clientId=u2755809b-38bf-4&from=paste&height=399&id=ufde0a9ed&margin=[object Object]&name=image.png&originHeight=429&originWidth=863&originalType=binary&ratio=1&size=175644&status=done&style=none&taskId=ued668556-34ec-4275-8a8e-5953a996139&width=802)

SpringAOP中, 通过Advice定义横切逻辑, Spring中支持5中类型的Advice:
![image.png](https://img-blog.csdnimg.cn/img_convert/7b49121f265568bf48692b402af13ec6.png#clientId=u2755809b-38bf-4&from=paste&height=486&id=u1fa3cba2&margin=[object Object]&name=image.png&originHeight=401&originWidth=665&originalType=binary&ratio=1&size=170676&status=done&style=none&taskId=u3f611206-ce66-4ec9-8dc3-691480bc845&width=806)
即AOP在不改变原有代码的情况下, 去增加新的功能

11.3、使用Spring实现AOP

**[重点]**使用AOP织入, 需要导入一个依赖包

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.7</version><scope>runtime</scope>
</dependency>

![image.png](https://img-blog.csdnimg.cn/img_convert/2e363dd43df57226aeb1a5e9ddba9739.png#clientId=u2755809b-38bf-4&from=paste&height=571&id=cMs2u&margin=[object Object]&name=image.png&originHeight=571&originWidth=1245&originalType=binary&ratio=1&size=315953&status=done&style=none&taskId=u49f34c0a-3ae8-48e5-b5de-a141d7438e8&width=1245)

方式一: 使用Spring的API接口

①配置beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>

②完整的beans.xml

<aop:config>
_
_<aop:pointcut id=“pointcut” expression="execution( com.service.UserServiceImpl.*())"*/>

_<!--执行环绕增加!--><br />    _<**aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"**/><br />    <**aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"**/><br />    _<!--意思是将beforeLog和afterLog这个类切入到目标类的指定地方--><br />_</**aop:config**>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!--注册bean--><bean id="userServiceImpl" class="com.service.UserServiceImpl"/><bean id="beforeLog" class="com.log.beforeLog"/><bean id="afterLog" class="com.log.afterLog"/><!--配置aop: 需要导入aop的约束--><aop:config><!--切入点: expression(表达式), execution(要执行的位置)[修饰词,返回值,类名,方法名,参数]--><aop:pointcut id="pointcut" expression="execution(* com.service.UserServiceImpl.*(..))"/><!--执行环绕增加!--><aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/><aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/><!--意思是将beforeLog和afterLog这个类切入到目标类的指定地方--></aop:config>
</beans>

③测试:

public class MyTest {public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");//动态代理代理的是接口: 注意点UserService userServiceImpl = context.getBean("userServiceImpl", UserService.class);//后面的参数是规定得到对象的类型userServiceImpl.add();}
}

注意: Spring AOP的底层是动态代理, 所以实现的是接口不是实现类

方式二: 使用自定义类

比方式一简单, 但少了一些功能
①配置beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>

②完整的beans.xml_<
<aop:config>
_
_<aop:aspect ref=“diy”>
_
_<aop:pointcut id=“point” expression="execution( com.service.UserServiceImpl.*(…))"*/>

_<!--通知(什么时候执行)--><br />    _<**aop:before method="before" pointcut-ref="point"**/><br />    <**aop:after method="after" pointcut-ref="point"**/><br />        _<!--意思是将diy类的before和after这两个方法切入到目标类的执行前和执行后--><br />    _</**aop:aspect**><br /></**aop:config**>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!--注册bean--><bean id="userServiceImpl" class="com.service.UserServiceImpl"/><bean id="diy" class="com.diy.diy"/><!--方式二: 自定义类--><aop:config><!--自定义切面(aspect), ref 要引用的自定义类--><aop:aspect ref="diy"><!--切入点--><aop:pointcut id="point" expression="execution(* com.service.UserServiceImpl.*(..))"/><!--通知(什么时候执行)--><aop:before method="before" pointcut-ref="point"/><aop:after method="after" pointcut-ref="point"/><!--意思是将diy类的before和after这两个方法切入到目标类的执行前和执行后--></aop:aspect></aop:config>
</beans>

③测试:

public class MyTest {public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans2.xml");//动态代理代理的是接口: 注意点UserService userServiceImpl = context.getBean("userServiceImpl", UserService.class);//后面的参数是规定得到对象的类型userServiceImpl.add();}
}

方式三: 使用注解实现

①切面类(注解)

//方式三: 使用注解方式实现AOP
@Aspect//标注这个类是一个切面(Aspect)
public class AnnotationPointCut {@Before("execution(* com.service.UserServiceImpl.*(..))")//写切入点(PointCut)。(方法)执行前public void before() {System.out.println("执行前");}@After("execution(* com.service.UserServiceImpl.*(..))")//写切入点(PointCut)。(方法)执行后public void after() {System.out.println("执行后");}//在环绕增强中,我们可以给定一个参数, 代表我们要获取处理切入的点@Around("execution(* com.service.UserServiceImpl.*(..))")//写切入点(PointCut)。(方法)执行后public void around(ProceedingJoinPoint jp) throws Throwable {//连接点(JoinPoint) 和切入点差不多,没什么用System.out.println("环绕前");Signature signature = jp.getSignature();//获得签名(执行的方法的信息)System.out.println("signature: " + signature);Object proceed = jp.proceed();//执行方法时()System.out.println("环绕后");}
}

②beans3.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!--注册bean--><bean id="userServiceImpl" class="com.service.UserServiceImpl"/><!--方式三: 使用注解方式实现AOP--><bean id="annotationPointCut" class="com.diy.AnnotationPointCut"/><!--开启注解支持--><aop:aspectj-autoproxy/>
</beans>

③测试

public class MyTest {public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans3.xml");//动态代理代理的是接口: 注意点UserService userServiceImpl = context.getBean("userServiceImpl", UserService.class);//后面的参数是规定得到对象的类型userServiceImpl.delete();}
}

注意:
开启注解支持 :
_JDK(默认 proxy-target-class=“false”) _
_cglib(需要手动设置 proxy-target-class=“true”)
结果不会有区别<**aop:aspectj-autoproxy proxy-target-class="false"**/>

PS: 环绕@Around
![image.png](https://img-blog.csdnimg.cn/img_convert/23ab7aadb3e96375acd39c78940ee0b2.png#clientId=u4943e8e5-6d30-4&from=paste&height=280&id=u3c3e8505&margin=[object Object]&name=image.png&originHeight=280&originWidth=760&originalType=binary&ratio=1&size=18456&status=done&style=none&taskId=u8d6e4627-1339-43a3-b9a5-caf271b6d2a&width=760)

11、AOP(重点)相关推荐

  1. 还不知道 AWS 是什么?这 11 个重点带你认识 AWS !

    作者 | Sajan Agrawal 译者 | 天道酬勤 责编 | 徐威龙 封图| CSDN 下载于视觉中国 云计算的出现使软件行业受益匪浅.大多数公司已经改变了策略,将现有的项目转移到云上,并在此基 ...

  2. 小米 11 的重点,和充电器无关

    在四千元价位的手机市场,你可能找不到另一个小米 11. 「这是小米有史以来做过的最漂亮的手机.」在距离 2021 年还剩 75 个小时的当口,雷军在小米科技园发布了新一代旗舰机,小米 11. 今年是小 ...

  3. 面试官问怎么进行代码优化,我一口气讲了11个重点

    1.选择合适的算法和数据结构 选择一种合适的数据结构很重要,如果在一堆随机存放的数中使用了大量的插入和删除指令,那使用链表要快得多.数组与指针语句具有十分密切的关系,一般来说,指针比较灵活简洁,而数组 ...

  4. Android AOP之字节码插桩

    背景   本篇文章基于<网易乐得无埋点数据收集SDK>总结而成,关于网易乐得无埋点数据采集SDK的功能介绍以及技术总结后续会有文章进行阐述,本篇单讲SDK中用到的Android端AOP的实 ...

  5. Spring之AOP由浅入深

    1.AOP的作用 在OOP中,正是这种分散在各处且与对象核心功能无关的代码(横切代码)的存在,使得模块复用难度增加.AOP则将封装好的对象剖开,找出其中对多个对象产生影响的公共行为,并将其封装为一个可 ...

  6. spring核心之AOP学习总结二

    一:springAOP常用的注解 @Aspect:声明方面组件 @Before:声明前置通知 @After-returning:声明后置通知 @After:声明最终通知 @Around:声明环绕通知 ...

  7. 从壹开始前后端分离【 .NETCore2.1 +Vue 2 +AOP+DI】框架之一 || 前言

    缘起 作为一个.Net攻城狮已经4年有余了,一直不温不火,正好近来项目不是很忙,闲得无聊,搞一搞新技术,一方面是打发无聊的时间,一方面也是督促自己该学习辣!身边的大神都转行的转行,加薪的加薪,本人比较 ...

  8. 电子城西区北扩规划一路道路工程_雁塔区电子城街道重点项目进度

    全年财税收入完成33353万元,占年度目标任务的101.2%:建筑业总产值完成165.84亿元,占年度目标任务的138.5%:规模以上工业总产值完成2.78亿元,占年度目标任务的98.23%:限额以上 ...

  9. 翻译 | 正式发布Qt 5.11

    本文翻译自:Qt 5.11 released 原文作者: Qt公司CTO兼Qt开源项目维护官Lars Knoll 翻译校审:Richard Lin.Hongfei Zhang.Haipeng Yu 本 ...

最新文章

  1. 计算机全球服务器,云计算的宿命:全球合并成一台计算机,支持无服务器运行...
  2. 深入Ajax架构和最佳实践读书笔记
  3. php中new运算符的作用,C++_C++编程中new运算符的使用学习教程,new运算符用作从自由存储为 typ - phpStudy...
  4. php图片生成缩略图_PHP生成图片缩略图类示例
  5. CSS float的相关图文详解(二)
  6. from flask.ext.cache import make_template_fragment_key
  7. 打印容器_3D打印:增材点阵结构在压力容器优化设计中的应用
  8. 前端学习(177):定义列表
  9. vue表格刷新数据_Vue.js的列表数据的同步更新方法
  10. 使用Jupter Notebook实现简单的神经网络
  11. 刚刚用上Ubuntu18,Ubuntu20已经出来了
  12. c#开发之八---mvc
  13. Jack魏--个人介绍
  14. php 真太阳时间修正,北京时间与真太阳时以及换算方法!
  15. css 改变图片的背景色,css3实现背景图片颜色修改的多种方式
  16. jinja2说明文档
  17. 在阿里云注册域名后如何网站备案
  18. 物联网技术,主要应用在哪些领域?
  19. 如何选择合适焦距工业相机镜头
  20. 20150609.C语言-尹成-专题视频课程

热门文章

  1. python各种常用符号的意思_写一篇专门介绍python中各种符号的意义及用法
  2. 素描零基础知道啥是三大面跟五调子…
  3. 剪花布条(Java)
  4. C#中的TemplateMethod模式
  5. (python3)kaggle上matplotlib显示不了中文(title是框,坐标也是框)完全解决.md
  6. 同款蓝牙耳机为什么会串联_使用蓝牙耳机到底好不好?有什么佩戴舒适的蓝牙耳机吗?...
  7. 成功开发新客户 必备十大技巧
  8. 创建react脚手架
  9. 萌妹子变脸奥巴马!外国小哥微调StyleGAN2和FFHQ,真人视频秒变卡通视频
  10. 关于安卓的一些残缺笔记