1.OOP和AOP
OOP(object-oriented Programming)
面向对象编程,将整个系统分解为由层次结构组成的对象
关注的方向是纵向
AOP(Aspect Oriented Programming)
面向方面编程,将整体分解成方面(aspect)
关注的方向是横向
在OOP中,日志代码水平地散布在所有对象层次中,而与它所散布到的对象的核心功能无关,这种散布在各处无关的代码被称为横切(cross-cutting)代码
在AOP中,采用横切技术,将那些影响了多个类的公共行为封装到一个可重用模块(aspect,方面)中,将应用程序中的商业逻辑同对其提供支持的通信服务进行分离
比较
OOP要在处理三个不同的业务逻辑时分别添加相同的日志记录和安全检测代码
AOP将日志记录和安全检测代码封装为方法,在处理业务逻辑前调用方法
有效解决重复性代码的问题,并为程序开发、调试带来极大方便
2.AOP的核心概念
AOP使用横切把软件分为了两个部分
核心关注点:业务处理的主要流程
横切关注点:与业务关系不大,发生在核心关注点的多出,且各处基本相似
实现AOP的技术,分为两类
动态代理:利用截取消息的方式,对消息进行装饰,以取代原有对象行为的执行
静态注入:引入特定的语法创建方面,从而使得编译器可以在编译期间注入有关方面的代码
实现AOP的技术特性:
join point(连接点):是程序执行中的一个精确执行时刻,例如类中的一个方法调用时刻、抛出异常的时刻,它是一个抽象概念,在实现AOP时,并不需要去定义一个join point
point cut(切入点):本质是一个捕获连接点的结构,在AOP中定义一个point cut,来捕获相关方法的调用,一般通过指定类名,方法名,或者通过匹配类名、方法名样式的正则表达式来指定切入点
advice(通知):是切入点的指向代码,是执行 “方面”的具体逻辑,分3中类型
before advice(前置性通知)
after advice(后置型通知)
around advice(环绕型通知)
通知都是以拦截器的形式来实现
aspect(方面):一个方面是对一个横切关注点的模块化
point cut+advice=aspect
将零散的关注点代码进行整合
它类似于OOP中定义一个类,但其更加代表的是类间的关系
introduce(引入):为对象引入附加的方法或属性,从而达到修改对象结构的目的,有的AOP工具称为mix in
target(目标对象):指定被通知的对象,该对象即可以是自己编写的类也可以是第三方类
weaving(织入):通过织入方式将方面应用到目标对象从而创建新的代理对象
3.Spring AOP简介
Spring AOP使用java实现,无需编译
Spring AOP中的一些AOP的核心概念发生了改变
aspect(切面):切面就是要横切加入的功能,如日志记录;将所有模块中的日志记录功能连接起来就可以形成一个切面,这个切面将各个应用模块顺序执行流程切断,在断点处加入日志记录功能
advisor(顾问):Spring框架中引入一个新的概念,一个advisor由advice(通知)和point cut(切入点)两部分组成,是代码模块化的aspect;在Spring框架中提供了大量的advisor实现,实际应用中可以直接使用
join point(连接点):Spring AOP中只支持Method Invocation(方法回调)连接点
advice(通知):Spring AOP提供两种通知的实现方式
实现Adviec接口:前置通知,后置通知
实现MethodInterceptor接口:是advice接口的子接口,它采用拦截器的方式提供了环绕型通知的实现方式
point cut(切入点):切入点是连接点的集合,用于指定程序中需要注入通知的位置,即在何种条件下发出的通知
interceptor(拦截器):使用拦截器对方法拦截,可以将多个功能构建成拦截器链
weaving(织入):将切面应用到目标对象而创建的一个新的代理对象的过程,通常由代理工程实现,程序执行前进行相应配置,容器就可以按照配置信息,在指定切入点将通知织入到系统
4.Spring 通知
Spring通知可以在方法调用的各个区间织入
使用不同的通知类型,能够确定在方法调用前、后或任意区间织入指定的通知
Spring包括的通知类型
BeforeAdvice,前置通知,在指定方法调用前将通知织入
AfterReturningAdvice,后置型通知,在指定方法被调用后将通知织入系统
MethodInterceptor,环绕型通知,在指定方法执行前后将通知织入系统,可以在一个被织入通知对象中同时实现两种通知
ThrowAdvice,异常通知
当指定方法调用过程中抛出异常时将通知织入系统
异常通知经常被用于事务管理,当在程序执行过程中发生异常,事务需要执行回滚操作
5.AOP横切技术
软件模块包括核心功能(核心关注)和通用功能(横切关注点)
AOP利用横切技术将横切关注点从模块中切出,变成方面
AOP横切技术分为
动态横切
通过切入点和连接点在一个方面创建行为的过程,连接点可以在执行时横向地应用于现有现象
通常用于帮助向对象层次中的各种方法添加日志记录或身份认证
在很多的应用场景中,动态横切技术基本代表了AOP
利用AOP技术,我们可以分离系统的核心关注点和横切关注点,从横向的角度,截取业务管理行为的内部消息,以达到织入权限管理逻辑的目的
静态横切
静态横切和动态横切的区别在于其不修改一个给定对象的执行行为。
相反,它允许通过引入附加的方法字段和属性来修改对象的结构。
此外,静态横切可以把扩展和实现附加到对象的基本结构中。
在AOP实现中,通常将静态横切称为introduce或者mixin
Spring切入点
静态切入点只限制给定的方法和目标类,而不考虑方法的参数,在多数情况下使用静态切入点可以满足需求
动态切入点不仅限定给定的方法和类,还需指定方法的参数,虽更加灵活,但比静态切入点性能低
6.Spring AOP的代理工厂
Spring AOP的核心工作原理是基于代理和代理工厂,当各个关注点由业务对象分离后,需要代理工厂为目标对象创建一个代理对象,以便使用AOP向业务逻辑中添加功能。Spring AOP可创建两种代理对象
Java动态代理:这种类型的代理只能针对接口生成代理对象,而不能生成类的代理对象,使用java动态代理对象必须实现至少一个接口。在使用时,所有的方法都会被拦截,并由程序根据切入点信息判断该方法是否需要织入通知。由于每次方法调用都要进行判断,所以使用java动态代理效率并不高
CGLIB代理:这种带来类型可以生成类级别的带来对象,它是针对字节码进行代理,不需要对每个方法进行拦截。性能要优于Java动态代理
ProxyFactory,在Spring AOP中,其使得我们不必依赖IoC容器而控制AOP的相关流程
执行时,ProxyFactory会调用DefaultAopProxyFactory来真正创建代理对象。根据设置不同,被创建的带来对象可以是Cglib2AopProxy(CGLIB代理对象),也可以是JdkDynamicAopProxy(java动态代理对象)
通过调用ProxyFactory的不同方法,可以在程序任意位置织入advisor或advice