面向切面的Spring系列一:什么是面向切面编程(AOP)

微信公众号:Java周刊
如有问题或建议,请公众号留言
最近更新:2018-03-24

在软件开发中,散布于应用中多处的功能被称为横切关注点(cross-cutting concern)。通常来讲,这些横切关注点从概念上是与应用的业务逻辑相分离的(但是往往会直接嵌入到应用的业务逻辑之中)。把这些横切关注点与业务逻辑相分离正是面向切面编程(AOP)所要解决的问题。

DI有助于应用对象之间的解耦,而AOP可以实现横切关注点与它们所影响的对象之间的解耦。
什么是面向切面编程?
我们在一个地方定义通用功能,但是可以通过声明的方式定义这个功能要以何种方式在何处应用,而无需修改受影响的类。横切关注点可以被模块化为特殊的类,这些类被称为切面(aspect)。

这样做有两个好处:
1.现在每个关注点都集中于一个地方,而不是分散到多处代码中;
2.服务模块更简洁,因为它们只包含主要关注点(或核心功能)的代码,而次要关注点的代码被转移到切面中了。

举个例子:比如在我们的系统中有,UserService、PayService、LogService,每种Service我们把它们称为组件,即我们这里有用户服务组件、支付服务组件、日志服务组件;同时以上的三种组件换种说法的话我们可以称为:用户服务关注点、支付服务关注点、日志服务关注点,但是通常像在我们的用户服务关注点、支付服务关注点等等这些组件中的多处都需要记录日志,所以我们把日志模块化成单独的关注点,并且日志关注点被应用在多个其他关注点之中,所以我们把像日志这样的关注点就称为横切关注点。
1. 定义AOP术语
大多数用于描述AOP功能的术语并不直观,尽管如此,它们现在已经是AOP行话的组成部分了,为了更好的理解AOP,我通过思维导图的方式梳理了这些概念。 不知道为什么CSDN插入图片不能显示,原图可以在我的公众号文章中看到。
2. Spring对AOP的支持
并不是所有的AOP框架都是相同的,如在下面两方面的区别:
1.它们在连接点模型上可能有强弱之分。有些允许在字段修饰符、构造器(类初始化)级别应用通知,而另一些只支持与方法调用相关的连接点。
2.它们织入切面的方式和时机也有所不同。但是无论如何,创建切点来定义切面所织入的连接点是AOP框架的基本功能。

Spring提供了4种类型的AOP支持:
1.基于代理的经典Spring AOP;
2.纯POJO切面;
3.@AspectJ注解驱动的切面;
4.注入式AspectJ切面(适用于Spring各版本)。

前三种都是Spring AOP实现的变体,Spring AOP构建在动态代理基础之上,因此,Spring对AOP的支持局限于方法拦截。

Spring提供了更简洁和干净的面向切面编程方式,引入了简单的声明式AOP和基于注解的AOP之后,Spring经典的AOP看起来就显得非常笨重和过于复杂。

借助Spring的aop命名空间,我们可以将纯POJO转换为切面。实际上,这些POJO只是提供了满足切点条件时所要调用的方法。但是,这种技术需要XML配置,但这的确是声明式地将对象转换为切面的简便方式。

Spring借鉴了AspectJ的切面,以提供注解驱动的AOP。本质上,它依然Spring基于代理的AOP,但是编程模型几乎与编写成熟的AspectJ注解切面完全一致。这种AOP风格的好处在于能够不使用XML来完成功能。

如果你的AOP需求超过了简单的方法调用(如构造器或属性拦截),那么你需要考虑使用AspectJ来实现切面。
2.1 Spring通知是Java编写的
Spring所创建的通知都是用标准的Java类编写的。这样的话,我们就可以使用与普通Java开发一样的集成开发环境(IDE)来开发切面。而且,定义通知所应用的切点通常会使用注解或在Spring配置文件里采用XML来编写,这两种语法对于Java开发者来说都是相当熟悉的。

AspectJ与之相反。虽然AspectJ现在支持基于注解的切面,但AspectJ最初是以Java语言扩展的方式实现的。
2.2 Spring在运行时通知对象
通过在代理类中包裹切面,Spring在运行期把切面织入到Spring管理的bean中。代理类封装了目标类,并拦截被通知方法的调用,再把调用转发给真正的目标bean。当代理拦截到方法调用时,在调用目标bean方法之前,会执行切面逻辑。

直到应用需要被代理的bean时,Spring才创建代理对象。如果使用的是ApplicationContext的话,在ApplicationContext从BeanFactory中加载所有bean的时候,Spring才会创建被代理的对象。因为Spring运行时才创建代理对象,所以我们不需要特殊的编译器来织入Spring AOP的切面。
2.3 Spring只支持方法级别的连接点
通过使用各种AOP方案可以支持多种连接点模型。因为Spring基于动态代理,所以Spring只支持方法连接点。这与一些其他的AOP框架是不同的,例如AspectJ和JBoss,除了方法切点,它们还提供了字段和构造器接入点。

参考资料:Spring In Action(FOURTH EDITION);开涛博客

喜欢本文,欢迎关注《Java周刊》

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值