在软件中,有些行为对于大多数应用都是通用的。比如:日志、安全和事务。如果每个方法里面都去写记日志的方法逻辑,是不是觉得很麻烦,耦合度过高。如果让应用对象只关注自己所针对的业务领域问题,而其他方面的问题由其他应用对象处理,这会不会更好了?
在软件开发中,分布于应用中多处的功能被称为横切关注点。通常,这些横切关注点从概念上是于应用的业务逻辑是分离的(但是往往直接嵌入到应用的业务逻辑之中)。将这些横切还珠点于业务逻辑相分离正是面向切面编程(AOP)所要解决的。
1、什么是面向切面编程
前面说了,切面能帮助我们模块化横切关注点,横切关注点可以被描述为影响应用多处的功能。例如:安全就是个横切关注点,应用中的许多方法都会涉及到安全规则。看下图(画的有点丑,见谅):
上图展现了一个被划分为模块的典型应用。每个模块都是为特定业务领域提供服务,但是这些模块都需要类似的辅助功能,例如:安全和事务管理。
事务和委托是最常见的实现重用通用功能的面向对象技术。但是如果在整个应用中使用相同的基类。因为Java是单继承,往往会导致一个脆弱的对象体系,使用委托可能需要对委托对象进行复杂调用。
然后切面提供了取代继承,委托的另一种选择,而且在很多场景下更能清晰简洁。在使用横向切面编程时,我们仍然在一个地方定义通用的功能,但是我们可以通过声明的方式定义这个功能以何种方式在何处使用,而无需修改受影响的类。横切关注点可以被模块化的特殊的类,这些类被成为切面。这么做的好处,首先关注点代码都集中在一处,而不是分散在多处代码中,代码服务模块更加清晰整洁。
2、AOP入门
n关注点:可以认为是所关注的任何东西;
n关注点分离:将问题细化为单独部分,即可以理解为不可再分割的组件,如上边的日志组件和支付组件;
n横切关注点:会在多个模块中出现,使用现有的编程方法,横切关注点会横越多个模块,结果是使系统难以设计、理解、实现和演进,如日志组件横切于支付组件。
织入:横切关注点分离后,需要通过某种技术将横切关注点融合到系统中从而完成需要的功能,因此需要织入,织入可能在编译期、加载期、运行期等进行。
3、AOP是什么(Aspect
Oriented Programming)
AOP是一种编程范式,提供从另一个角度来考虑程序结构以完善面向对象编程(OOP)。
AOP为开发者提供了一种描述横切关注点的机制,并能够自动将横切关注点织入到面向对象的软件系统中,从而实现了横切关注点的模块化。
AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任,例如事务处理、日志管理、权限控制等,封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。
4、AOP能干什么,也是AOP带来的好处
1:降低模块的耦合度
2:使系统容易扩展
3:设计决定的迟绑定:使用AOP,设计师可以推迟为将来的需求作决定,因为它
可以把这种需求作为独立的方面很容易的实现。
4:更好的代码复用性
5、AOP基本概念
连接点(Joinpoint):
表示需要在程序中插入横切关注点的扩展点,连接点可能是类初始化、方法执行、方法调用、字段调用或处理异常等等,Spring只支持方法执行连接点,在AOP中表示为“在哪里做”;
切入点(Pointcut):
选择一组相关连接点的模式,即可以认为连接点的集合,Spring支持perl5正则表达式和AspectJ切入点模式,Spring默认使用AspectJ语法,在AOP中表示为“在哪里做的集合”;
通知(Advice):
在连接点上执行的行为,增强提供了在AOP中需要在切入点所选择的连接点处进行扩展现有行为的手段;在Spring中通过代理模式实现AOP,并通过拦截器模式以环绕连接点的拦截器链织入增强 ;在AOP中表示为“做什么”;
- Before——在方法被调用之前通知
- After——在方法完成之后调用通知,无论方法是否执行成功
- After-returing——在方法成功执行之后执行通知
- After-throwing——在方法抛出异常后调用通知
- Around——通知包裹了被通知方法,在被通知的方法调用之前和调用之后执行自定义的行为
切面(Aspect):
横切关注点的模块化,比如上边提到的日志组件。可以认为是增强、引入和切入点的组合;在Spring中可以使用Schema和@AspectJ方式进行组织实现;在AOP中表示为“在哪里做和做什么集合”;
引入(inter-type declaration):
也称为内部类型声明,为已有的类添加额外新的字段或方法,Spring允许引入新的接口(必须对应一个实现)到所有被代理对象(目标对象), 在AOP中表示为“做什么(新增什么)”;
织入(Weaving):
织入是一个过程,是将切面应用到目标对象从而创建出AOP代理对象的过程,织入可以在编译期、类装载期、运行期进行。
6、spring对AOP的支持
Spring提供了4种各具特色的AOP支持:
- 基于代理的经典AOP
- @AspectJ注解驱动的切面
- 纯POJO切面
- 注入式AspectJ切面(适合各版本)
前面三种都是Spring基于代理的AOP变体,因此Spring对AOP的支持局限于方法拦截。如果AOP需要进行构造器拦截或属性拦截,那么应该考虑用AspectJ里实现切面,利用Spring的DI把Spring Bean注入到AspectJ切面中。
版权声明:本文为博主原创文章,未经博主允许不得转载。