Spring Aop源码阅读&循环依赖问题
什么是AOP
- 再软件行业,Aop为Aspect Oriented Programming的缩写,意为:面向切面编程
- AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生泛型
- 作用:再不修改【目标类代码】的前提下,可以通过AOP技术去【增强目标类的功能】。通过【预编译方式】或者【运行期动态代理】实现程序功能的统一维护的一种技术
- 对目标类进行无感知的功能增强。
- AOP是一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构
- AOP最早由AOP联盟的组织提出的,制定了一套规范。Spring将AOP思想引入到框架中,必须遵守AOP联盟的规范
- 利用AOP可以对业务代码中【业务逻辑】和【系统逻辑】进行隔离,从而使得【业务逻辑】和【系统逻辑】直接的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
为什么使用AOP
业务层存在的问题:
需要改善的地方:
- 抽象共性代码(系统功能)
- 将代码职责分离(系统功能,业务功能)
- 保证代码的扩展性
- 作用:
AOP采取横向抽取机制,补充了传统纵向继承体系(OOP)无法解决的重复性代码优化(性能监视,事务管理,安全检测,缓存),将业务逻辑和系统处理的代码(关闭连接,事务管理,操作日志记录)解耦。 - 优势:
重复性代码被抽取处理之后,维护更加方便
不想修改原有代码前提下,可以动态横向添加共性代码。
AOP相关术语介绍
-
Joinpoint(连接点)
-
Pointcut(切入点)
-
Advice(通知/增强)
-
Introduction(引介)
-
Target(目标对象)
-
Weaving(织入)
-
Proxy(代理)
-
Aspect(切面)
-
Advisor(通知面,顾问)
AOP实现只AspectJ(了解)
- AspectJ是一个Java实现的AOP框架,它能够对java代码进行AOP编译(一般在编译器进行),让java代码局有AspectJ的AOP功能(当然需要特殊的编译器)
- 可以这样说AspectJ是目前实现的AOP框架中最成熟,功能最丰富的语言。更幸运的是,AspectJ与Java程序完全兼容,几乎是无缝关联,因此对于有java编程基础的工程师,上手和使用都非常容易
- 了解AspectJ应用到java代码的过程(这个过程称为织入),对于织入这个概念,可以简单理解为aspect(切面)应用到目标函数(类)的过程
- 对于织入这个过程,一般分为静态织入和动态织入,动态织入的方式是在运行时动态将要增强的代码织入到目标类中,这样往往是通过动态代理技术完成的,如Java JDK的动态代理(Proxy,底层通过反射实现)或者CGLIB的动态代理(底层通过继承实现),Spring Aop采用的就是基于运行时增强代理技术
- ApectJ采用 的就是静态织入的方式,AspectJ主要采用的是编译器织入,在这个期间使用AspectJ的acj编译器(类似javac)把aspect类编译成class字节码后,在java目标类编译时织入,即先编译aspect类再编译目标类。
AOP实现之Spring Aop(了解)
实现原理分析
- Spring AOP是通过动态代理技术实现的
- 而动态代理是基于反射设计的。
- 动态嗲了技术的实现方式有俩种:基于接口的JDK动态代理和基于继承的CGLIB动态代理
JDK动态代理
目标对象必须实现接口
Cglib动态代理
- 目标对象不需要实现接口
- 底层是通过继承目标对象产生代理子对象(代理子对象中继承了目标对象的方法,并可以对该方法进行增强)
ASM API使用
使用
- 其实现ProxyFactoryBean创建
- 使用aop:advisor定义通知器的方式实现AOP则需要通知类实现Advice接口
- 增强(通知)的类型有:
基于AspectJ的AOP使用
其实就是指的Spring+AspectJ整合,不过Spring以及将AspectJ收录到自身的框架中了,并且底层织入依然是采取的动态织入方式。
切入点表达式
切入点表达式的格式:
表达式格式说明:
-
execution:必须要
-
修饰符:可省略
-
返回值类型:必须要,但是可以使用*通配符
-
包名:
-
类名
-
方法名:
-
参数
通知类型
通知类型(五种):前置通知,后置通知,最终通知,环绕通知,异常抛出通知。
前置通知:
后置通知:
最终通知:
环绕通知:
异常抛出通知:
使用注解实现
-
编写切面类(注意不是通知类,因为该类中可以指的切入点)
-
环绕通知注解
@Around -
定义通用切入点
使用@PointCut注解再切面类中定义一个通用的切入点,其他通知可以引用该切入点
纯注解方式
代理模式
其实每个模式名称就表明了该模式的作用,戴爱玲模式就是多一个代理类出来替原对象进行一些操作。代理又分为动态代理和静态代理。
静态代理
比如租房子找中介
静态代理的重点:
- 需要为源类手动编写一个代理类
- 代理类和源类实现同一接口。
- 代理对象持有源对象的引用。
静态代理的缺点:
- 会产生大量的代理类。
代理模式的应用场景:
如果已有的方法再使用的时候需要对原有的方法进行改进,此时有俩种办法:
- 修改原有的方法来适应,这样违反了“对扩展开发,对修改关闭”的原则
- 就是采用一个代理类调用原有的方法,且对产生的结果进行控制。这种方法就是代理模式。
使用代理模式,可以将功能划分的更加清晰,有助于后期维护!
动态代理
动态代理再编译期间,不需要为源类去手动编写一个代理类
只会再运行期间,去为源对象产生一个代理对象。
JDK动代理和Cglib动态代理的区别
文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树首页概览91280 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!