什么是aop

AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

什么是aop.png

而AOP技术则恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。

aop使用场景

aop框架种类

  • AspectJ

  • JBoss AOP

  • Spring AOP

使用aop可以做的事情有很多。

  • 性能监控,在方法调用前后记录调用时间,方法执行太长或超时报警。

  • 缓存代理,缓存某方法的返回值,下次执行该方法时,直接从缓存里获取。

  • 软件破解,使用AOP修改软件的验证类的判断逻辑。

  • 记录日志,在方法执行前后记录系统日志。

  • 工作流系统,工作流系统需要将业务代码和流程引擎代码混合在一起执行,那么我们可以使用AOP将其分离,并动态挂接业务。

  • 权限验证,方法执行前验证是否有权限执行当前方法,没有则抛出没有权限执行异常,由业务代码捕捉。

观察一下传统编码方式与使用aop的区别

3种日志处理.png

核心概念

描述AOP常用的一些术语有通知(Adivce)、切点(Pointcut)、连接点(Join point)、切面(Aspect)、引入(Introduction)、织入(Weaving)、通知(Advice)等。

aop重要概念.png

简单例子

相比xml配置,基于注解的方式更加简洁方便。

 @Aspectpublic class TransactionDemo {

     @Pointcut(value="execution(* com.yangxin.core.service.*.*.*(..))")    public void point(){

     }

     @Before(value="point()")    public void before(){
System.out.println("transaction begin");
} @AfterReturning(value = "point()") public void after(){
System.out.println("transaction commit");
} @Around("point()") public void around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("transaction begin");
joinPoint.proceed();
System.out.println("transaction commit");
}
}

在applicationContext.xml中配置。

<aop:aspectj-autoproxy />
<bean id = "transactionDemo" class = "com.yangxin.core.transaction.TransactionDemo" />

spring aop原理

通过前面介绍可以知道:AOP 代理其实是由 AOP 框架动态生成的一个对象,该对象可作为目标对象使用。AOP 代理包含了目标对象的全部方法,但 AOP 代理中的方法与目标对象的方法存在差异:AOP 方法在特定切入点添加了增强处理,并回调了目标对象的方法。

代理的方法与目标对象的方法.png

Spring 的 AOP 代理由 Spring 的 IoC 容器负责生成、管理,其依赖关系也由 IoC 容器负责管理。因此,AOP 代理可以直接使用容器中的其他 Bean 实例作为目标,这种关系可由 IoC 容器的依赖注入提供。

aop开发时,其中需要程序员参与的只有 3 个部分:

  • 定义普通业务组件。

  • 定义切入点,一个切入点可能横切多个业务组件。

  • 定义增强处理,增强处理就是在 AOP 框架为普通业务组件织入的处理动作。

为了理清关系,先来个类关系图。

Spring中主要的AOP组件.png

两种动态代理方式

Spring默认采取的动态代理机制实现AOP,当动态代理不可用时(代理类无接口)会使用CGlib机制。

Spring提供了两种方式来生成代理对象: JDKProxy和Cglib,具体使用哪种方式生成由AopProxyFactory根据AdvisedSupport对象的配置来决定。默认的策略是如果目标类是接口,则使用JDK动态代理技术,否则使用Cglib来生成代理。

JDK动态代理

  • JDK动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler。InvocationHandler是一个接口,通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态将横切逻辑和业务逻辑编制在一起。

  • Proxy利用InvocationHandler动态创建一个符合某一接口的实例,生成目标类的代理对象。

CGLib动态代理

  • CGLib全称为Code Generation Library,是一个强大的高性能,高质量的代码生成类库,可以在运行期扩展Java类与实现Java接口,CGLib封装了asm,可以再运行期动态生成新的class。和JDK动态代理相比较:JDK创建代理有一个限制,就是只能为接口创建代理实例,而对于没有通过接口定义业务方法的类,则可以通过CGLib创建动态代理。

知识拓展

通过上面的分析,大家是否有种熟悉的感觉,似乎和拦截器、过滤器的功能相似。那么问题来了,aop与拦截器、过滤器是什么关系。

先来回顾一下拦截器与过滤器。如下图一网友的测试,在web.xml中注册了TestFilter1和TestFilter2。然后在spring的配置文件中配置了BaseInterceptor和TestInterceptor。得到的结果如下图所示。从图中可以看出,拦截器和过滤器都横切了业务方法,看似符合aop的思想。

拦截器和过滤器.png

Filter过滤器:拦截web访问url地址。
Interceptor拦截器:拦截以 .action结尾的url,拦截Action的访问。
Spring AOP拦截器:只能拦截Spring管理Bean的访问(业务层Service)

拦截器与过滤器.png

参考文档:https://mp.weixin.qq.com/s/6WK2oV-vaqPGQpIIR5UeHA

让Spring不再难懂-aop篇的更多相关文章

  1. 让Spring不再难懂-ioc篇

    写过java的都知道:所有的对象都必须创建:或者说:使用对象之前必须先创建.而使用ioc之后,你就可以不再手动创建对象,而是从ioc容器中直接获取对象. 就好像我们无需考虑对象的销毁回收一样,因为ja ...

  2. 让Spring不再难懂-mvc篇

    spring mvc简介与运行原理 Spring的模型-视图-控制器(MVC)框架是围绕一个DispatcherServlet来设计的,这个Servlet会把请求分发给各个处理器,并支持可配置的处理器 ...

  3. Spring思维导图,让spring不再难懂(一)

    写在前面 很多人在微信公众号中给我留言说想看spring的思维导图,正好也打算写.与其他框架相比,spring项目拥有更多的模块,我们常用的ioc,mvc,aop等,这些是spring的主要板块.一篇 ...

  4. Spring入门之AOP篇

    听了几节IT黑马营的SPRING课程,照着例程写了一个SPRING 中AOP的例子:  一.准备工作 下载复制或配置JAR包.图方便,我将下载的SPRING包都加上去了.另外还需要aspectj的两个 ...

  5. Spring思维导图(AOP篇)

    什么是aop AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP允许 ...

  6. 死磕Spring之AOP篇 - Spring AOP注解驱动与XML配置

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...

  7. 死磕Spring之AOP篇 - Spring AOP常见面试题

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...

  8. 死磕Spring之AOP篇 - 初识JDK、CGLIB两种动态代理

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...

  9. 死磕Spring之AOP篇 - Spring AOP总览

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...

随机推荐

  1. Linux(CENTOS7) YUM方式安装mysql5.7

    参考地址:https://www.cnblogs.com/linjiqin/p/7611204.html 注:该地址标题写的是CENTOS6.*版本的,但是我在我的CENTOS7.*上面安装是完美进行 ...

  2. 关于typedef的一些小知识

    //关于typedef //1.在c语言中定义一个结构体typedef struct student{ int a;}stu;//typedef 给结构体起了个别名 stu;//于是,在声明变量的时候 ...

  3. zTree & ckeditor &ValidateCode.jar 使用个人心得总结

    zTree:依靠 jQuery 实现的多功能 “树插件”. 使用时只需要将下载的压缩包接用,复制里边的css 和 js 到指定目录即可. 如图所示: 在zTree的官网可以找到各种类型树的示例: 地址 ...

  4. UVA 12663 第九届省赛 高桥与低桥 线段树

    题意很简单,n个桥的高度是事先给出来的,然后有m次涨水与落水的高度,问有多少座桥在这m次涨落之后 被淹超过了k次,如果某桥本身被水淹了,此时再涨水,就不能算多淹一次 看下数据10的五次方,10的五次方 ...

  5. 查找ARP攻击源

    问题: 内网有电脑中了ARP病毒,但是网络拓扑比较复杂.电脑数量较多,排查起来很困难.有什么方法可以找出ARP攻击源?[推荐3]排查方法: 1.使用Sniffer抓包.在网络内任意一台主机上运行抓包软 ...

  6. Neo4j图形数据库备份

    Neo4j图形数据库备份 backup.sh文件 nowtime=`date +"%Y-%m-%d_%H_%M"` #原文件路径 sourcepath='/home/neo4j/n ...

  7. UML-用例关联

    1.用例关联:就是各个用例之间的关系,分3种关系分别是:包含关系.扩展关系.泛化关系. 2.包含关系 1).示例 2).使用场景 A.用例在其他用例中重复使用 B.用例非常复杂冗长,将其分解为子单元便 ...

  8. Java程序员想年后跳槽,对JVM没有深入的理解,我劝你还是别跳了

    前言 Java 虚拟机是学习 Java 的基础,也是迈入高级 Java 开发工程师的必备知识点.所以今天这篇文章我们来聊聊如何从零开始学习 Java 虚拟机. 深入浅出Java虚拟机 对于刚刚接触 J ...

  9. while read line do done < file

    zzx@zzx120:~/test1$ cat file.txt    1122zzx@zzx120:~/test1$ cat ./read.sh #!/bin/bashwhile read line ...

  10. Spring Cloud Alibaba 教程 | Nacos(一)

    什么是Nacos Nacos是一个更易于构建云原生应用的动态服务发现.配置管理和服务管理平台. Nacos 致力于帮助您发现.配置和管理微服务.Nacos提供了一组简单易用的特性集,帮助您快速实现动态 ...