Spring AOP概念理解 (通俗易懂)_如何理解spring中的aop-程序员宅基地

源地址:http://www.verydemo.com/demo_c143_i20837.html


  1.我所知道的aop

  初看aop,上来就是一大堆术语,而且还有个拉风的名字,面向切面编程,都说是OOP的一种有益补充等等。一下子让你不知所措,心想着:怪不得很多人都和我说aop多难多难。当我看进去以后,我才发现:它就是一些java基础上的朴实无华的应用,包括ioc,包括许许多多这样的名词,都是万变不离其宗而已。

  2.为什么用aop

  1就是为了方便,看一个国外很有名的大师说,编程的人都是“懒人”,因为他把自己做的事情都让程序做了。用了aop能让你少写很多代码,这点就够充分了吧

  2就是为了更清晰的逻辑,可以让你的业务逻辑去关注自己本身的业务,而不去想一些其他的事情,这些其他的事情包括:安全,事物,日志等。

 3.那些aop的术语

  初看这么多术语,一下子都不好接受,慢慢来,很快就会搞懂。

    1.通知(Advice)

  就是你想要的功能,也就是上面说的 安全,事物,日志等。你给先定义好把,然后在想用的地方用一下。

    2.连接点(JoinPoint)

  这个更好解释了,就是spring允许你使用通知的地方,那可真就多了,基本每个方法的前,后(两者都有也行),或抛出异常时都可以是连接点,spring只支持方法连接点.其他如aspectJ还可以让你在构造器或属性注入时都行,不过那不是咱关注的,只要记住,和方法有关的前前后后(抛出异常),都是连接点。

    3.切入点(Pointcut)

  上面说的连接点的基础上,来定义切入点,你的一个类里,有15个方法,那就有几十个连接点了对把,但是你并不想在所有方法附近都使用通知(使用叫织入,以后再说),你只想让其中的几个,在调用这几个方法之前,之后或者抛出异常时干点什么,那么就用切点来定义这几个方法,让切点来筛选连接点,选中那几个你想要的方法。

    4.切面(Aspect)

  切面是通知和切入点的结合。现在发现了吧,没连接点什么事情,连接点就是为了让你好理解切点,搞出来的,明白这个概念就行了。通知说明了干什么和什么时候干(什么时候通过方法名中的before,after,around等就能知道),而切入点说明了在哪干(指定到底是哪个方法),这就是一个完整的切面定义。

    5.引入(introduction)

  允许我们向现有的类添加新方法属性。这不就是把切面(也就是新方法属性:通知定义的)用到目标类中吗

    6.目标(target)

  引入中所提到的目标类,也就是要被通知的对象,也就是真正的业务逻辑,他可以在毫不知情的情况下,被咱们织入切面。而自己专注于业务本身的逻辑。

    7.代理(proxy)

  怎么实现整套aop机制的,都是通过代理,这个一会给细说。

    8.织入(weaving)

  把切面应用到目标对象来创建新的代理对象的过程。有3种方式,spring采用的是运行时,为什么是运行时,后面解释。

  关键就是:切点定义了哪些连接点会得到通知

  4.我所理解的aop原理

  spring用代理类包裹切面,把他们织入到Spring管理的bean中。也就是说代理类伪装成目标类,它会截取对目标类中方法的调用,让调用者对目标类的调用都先变成调用伪装类,伪装类中就先执行了切面,再把调用转发给真正的目标bean。

  现在可以自己想一想,怎么搞出来这个伪装类,才不会被调用者发现(过JVM的检查,JAVA是强类型检查,哪里都要检查类型)。

  1.实现和目标类相同的接口,我也实现和你一样的接口,反正上层都是接口级别的调用,这样我就伪装成了和目标类一样的类(实现了同一接口,咱是兄弟了),也就逃过了类型检查,到java运行期的时候,利用多态的后期绑定(所以spring采用运行时),伪装类(代理类)就变成了接口的真正实现,而他里面包裹了真实的那个目标类,最后实现具体功能的还是目标类,只不过伪装类在之前干了点事情(写日志,安全检查,事物等)。

  这就好比,一个人让你办件事,每次这个时候,你弟弟就会先出来,当然他分不出来了,以为是你,你这个弟弟虽然办不了这事,但是他知道你能办,所以就答应下来了,并且收了点礼物(写日志),收完礼物了,给把事给人家办了啊,所以你弟弟又找你这个哥哥来了,最后把这是办了的还是你自己。但是你自己并不知道你弟弟已经收礼物了,你只是专心把这件事情做好。

  顺着这个思路想,要是本身这个类就没实现一个接口呢,你怎么伪装我,我就压根没有机会让你搞出这个双胞胎的弟弟,那么就用第2种代理方式,创建一个目标类的子类,生个儿子,让儿子伪装我

  2.生成子类调用,这次用子类来做为伪装类,当然这样也能逃过JVM的强类型检查,我继承的吗,当然查不出来了,子类重写了目标类的所有方法,当然在这些重写的方法中,不仅实现了目标类的功能,还在这些功能之前,实现了一些其他的(写日志,安全检查,事物等)。

  这次的对比就是,儿子先从爸爸那把本事都学会了,所有人都找儿子办事情,但是儿子每次办和爸爸同样的事之前,都要收点小礼物(写日志),然后才去办真正的事。当然爸爸是不知道儿子这么干的了。这里就有件事情要说,某些本事是爸爸独有的(final的),儿子学不了,学不了就办不了这件事,办不了这个事情,自然就不能收人家礼了。

  前一种兄弟模式,spring会使用JDK的java.lang.reflect.Proxy类,它允许Spring动态生成一个新类来实现必要的接口,织入通知,并且把对这些接口的任何调用都转发到目标类。

  后一种父子模式,spring使用CGLIB库生成目标类的一个子类,在创建这个子类的时候,spring织入通知,并且把对这个子类的调用委托到目标类。

  相比之下,还是兄弟模式好些,他能更好的实现松耦合,尤其在今天都高喊着面向接口编程的情况下,父子模式只是在没有实现接口的时候,也能织入通知,应当做一种例外。


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qukaiwei/article/details/50367761

智能推荐

发那科机器人六轴放大器保险丝熔断_发那科机器人R-30iB控制柜保险丝解析——发那科机器人...-程序员宅基地

文章浏览阅读3.8k次。发那科机器人R-30iB控制柜保险丝解析一. 电源单元的保险丝F1-AC 输入保险丝 (A60L-0001-0450#8R0)F3-+24E用保险丝 (A60L-0001-0046#7.5)F4-+24V用保险丝 (A60L-0001-0046#7.5)二. 放大器的保险丝FS1:用于产生放大器控制电路的电源 ..._发那科机器人六轴放大器保险丝熔断

android滑动更改字体大小_android 横向拖动改变字体大小-程序员宅基地

文章浏览阅读770次。android滑动更改字体大小需求:用户自定义apk字体大小解决方法:第一步:需要更改大小的字体布局设置大小android:textSize=“14sp”,不需要更改大小的字体布局设置大小android:textSize=“14dp”,第二步:在Constants中加入代码 public static double fontsize=1; //当前字体缩放大小 /** * 将字符串数据保存到本地 * * @param context 上下文 * _android 横向拖动改变字体大小

一个屌丝程序猿的人生(十)-程序员宅基地

文章浏览阅读8.4k次,点赞63次,收藏2次。“哎,请先等一下。”  一个动听悦耳的声音在林萧身后响起。林萧发誓,在他的印象中,这是他从出生到现在听到过最好听的声音。  “你......叫我吗?”转过身后,林萧手指着自己疑惑的问道。  “恩恩,就是你。”前台小妹拿着简历晃了晃,点了点头说道。  林萧无法形容自己此刻的心情,有激动、有心酸、有紧张,还有那一闪即逝的茫然。  前台小妹说完以后,就拿着林萧的简

图片优化-程序员宅基地

文章浏览阅读94次。前面的话  本文将详细介绍前端项目中的图片相关的优化方案图片格式  目前在前端的开发中常用的图片格式有jpg、png、gif,png8、png24、png32、svg和webp【gif】  gif是无损的,具有文件小、支持动画及透明的优点。但gif无法支持半透明,且仅支持8bit的索引色,即在整个图片中,只能存在256种不同的颜色  但实际上,gif是一种逐渐被抛弃的..._customer scrollable element

Notepad++配合FingerText打造快速高效的前端开发文本编辑器_fingertext替代-程序员宅基地

文章浏览阅读1.2w次,点赞6次,收藏4次。Finger Text是Notepad++的一个标签代码替换和文本自动完成插件。Notepad++配合标签替换功能可以极大的提升编码速度,提高工作效率。也许有人使用过QuickText插件,它们的功能类似,在早期尤其是Xp版本上是非常好用的,不过已经停止更新了,在Win7版本上没有办法使用,在XP上还是可以接着用的,不过已经被Notepad++从官方的插件列表里移除了。安装Finger T_fingertext替代

来看看腾讯/阿里/百度 BAT人才体系的职位层级薪酬和晋升标准,作为Android程序员的你还差多少?_腾讯t11相当于阿里p几-程序员宅基地

文章浏览阅读1w次,点赞4次,收藏6次。互联网圈有这么一句话:百度的技术,阿里的运营,腾讯的产品。那么代表互联网三座大山的BAT,内部人才体系有什么区别呢?最新技术职级序列是如何划分的?不同职级之间的晋升难度有多大,如何评审?校招、社招程序员想去大厂应该如何准备?今天我就带领大家看一看~★ 腾讯 ★1. 职级腾讯职级体系分6级,最低1级,最高6级。同时按照岗位又划分为四大通道,内部也叫“族”,比如:产品/项目通道..._腾讯t11相当于阿里p几

随便推点

(python)undetected_chromedriver浏览器自动化测试-程序员宅基地

文章浏览阅读3.4k次,点赞3次,收藏13次。是一个用于绕过 Web 自动化中的 ChromeDriver 检测的 Python 库。它提供了更好的隐匿性和稳定性.适用于以下场景:可以用于模拟用户在浏览器中的操作进行自动化测试,例如填写表单、点击按钮、抓取页面内容等。由于其对驱动程序的检测绕过能力,可以帮助您避免被网站检测到并防止启动时的安全问题。在进行网页数据爬取时也能够提供更高的隐匿性。它可以模拟浏览器行为,如加载 JavaScript、执行 Ajax 请求等,从而获取动态生成的内容。_undetected_chromedriver

记一次sentry部署过程_warning: image for service backend was built becau-程序员宅基地

文章浏览阅读2.2k次。本文记录下部署sentry和其中遇到的问题 Sentry 是一款基于 Django实现的错误日志收集和聚合的平台,它是 Python 实现的,但是其日志监控功能却不局限于python,对诸如 Node.js, php,ruby, C#,java 等语言的项目都可以做到无缝集成,甚至可以用来对iOS, Android 移动客户端以及 Web前端异常进行跟踪。我们可以在程序中捕获异常,..._warning: image for service backend was built because it did not already exis

工作日志2018.03.19~2018.03.25_d 1_2018_03_03_19_26_35 e-程序员宅基地

文章浏览阅读218次。1、改进Arduino主控板的PCB板,主要是对地线进行改进,上版本的pcb图,所有地线没有连接在一起,这次投板,将所有地线连接在一起,并对地线的环绕进行优化,改好后,将板子投出去,投到嘉立创,这次投板版本是Arduino主控_V2.3_2018.03.19_投板;2、开会确认本周工作任务:(1)学习Microbit,包括所有硬件软件、使用;(2)四旋翼培训的事;(3)焊接5块左右Arduino主..._d 1_2018_03_03_19_26_35 e

Oracle11g R2 RAC 启动与停止顺序_rac停止一个节点 crs 还是 has-程序员宅基地

文章浏览阅读742次。停止的过程: 停止数据库实例-> 停止HAS-> 停止CRS, 启动的过程与之相反 关闭过程(CRS集群关闭->关闭数据库)1.关闭数据库: 用oracl用户执行srvctl命令 语法:srvctl stop database -d dbname [-o immediate] 作用:可以一次性关闭dbname的所有实例[Oracle@rac1 ~]$ srvc..._rac停止一个节点 crs 还是 has

Jetpack架构组件 — Room入坑详解_jetpack room kapt-程序员宅基地

文章浏览阅读350次。Room是Jetpack组件库一员,属于ORM库,主要是对Sqlite做了一层抽象,从而简化开发者对数据库操作。Room支持编译时的语法检查,并且支持返回LiveData。添加依赖在app的build.gradle中添加如下依赖:def room_version = "2.2.0-rc01"implementation "androidx.room:room-runtime:$room_version"// For Kotlin use kapt instead of annota_jetpack room kapt

推荐文章

热门文章

相关标签