目录
-
什么是AOP
AOP: Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译和运行期动态代理的方式实现程序功能的统一维护的一种技术。
主要功能:日志记录、性能统计、安全控制、事物管理、异常处理等。
实现方式:
(1)预编译——AspectJ
(2)运行期动态代理(JDK动态代理、CGLib动态代理)——SpringAOP、JbossAOP
-
AOP几个相关概念
切面(Aspect ):一个关注点的模块化,这个关注点可能会横切多个对象
连接点(Joinpoint):程序执行过程中的某个特定的点
通知(Advice):在切面的某个特定的连接点上执行的动作。通知分为:前置通知、后置通知、异常通知、最终通知、环绕通知(切面要完成的功能)。
切入点(Pointcut):匹配连接点的断言,在AOP中通知和一个切入点表达式关联
引入(Introduction):在不修改类代码的前提下,为类添加新的方法和属性
目标对象(Target Object):被一个或者多个切面所通知的对象
AOP代理(AOP Proxy):AOP框架所创建的对象,用来实现切面契约(aspect contract)(包括通知方法执行等功能)
织入(Weaving):把切面连接到其它的应用程序类型或者对象上,并创建一个被通知的对象,分为:编译时织入、类加载时织入、执行时织入
目标对象(Target):代理的目标对象
代理(Proxy):一个类被AOP织入增强后,就产生一个结果代理类
-
通知Advice类型
前置通知(Before Advice):在某个连接点之前执行的通知,但不能阻止连接点前的执行(除非它抛出一个异常)
前置通知(After returning Advice):在某个连接点正常完成后执行的通知
异常通知(After throwing advice):在方法抛出异常退出时执行的通知
最终通知(After(finally) advice):当某个连接点退出的时候执行的通知(不论是正常返回还是异常退出)
环绕通知(Around advice):包围一个连接点的通知
-
Spring框架中的AOP的用途
(1)提供了声明式的企业服务,特别是EJB的替代服务的声明
(2)允许用户定制自己的方面,以完成OOP与AOP的互补使用
什么是声明式?
声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。
-
Spring的AOP实现
1)纯java实现,无需特殊的编译过程,不需要控制类加载器的层次
2)目前只支持方法执行连接点(通知Spring Bean的方法执行)
3)并没有提供最完整的AOP实现,而是侧重于提供一种AOP实现和Spring IOC容器之间的整合,用于帮助解决企业应用中的常见问题
4)Spring AOP支持AspectJ,从而提供综合全面的AOP解决方案
注:AspectJ提供了全面的AOP实现,较传统AOP开发灵活很多,实际开发中推荐使用AspectJ AOP。
-
有接口和无接口的Spring AOP实现区别
1)有接口,Spring AOP默认使用标准的JavaSE动态代理作为AOP代理,这使得任何接口(或者接口集)都可以被代理
2)无接口,Spring AOP中也可以使用CGLIB代理(如果一个业务对象并没有实现一个接口)
-
预编译、运行期代理底层原理
在Spring 中,引入了AspectJ的语法,他本质上使用的是动态代理的方式。
动态代理,分两种实现模式:
1.使用接口(动态代理)
如果被代理的对象是面向接口编程的,那么Spring直接使用实现这些接口,然后把需要插入的内容在这个接口上下文中插入
2.使用继承(CGLIB)
如果被代理的对象没有基于接口编程,那么Spring会调用cglib库,通过子类继承的方式,动态插入需要的内容,并且调用父类的方法实现。
cglib内部拥有一个小的字节码处理框架asm,来转换字节码生成新的类.所以spring调用了cglib,相当于生成了一个被代理对象的子类,来取代被代理对象