Spring AOP

1、什么是AOP?

AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。

          对比OOP来说:OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

         AOP技术则恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。

        实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。


2、AOP的使用场景

Authentication 权限

Caching 缓存

Context passing 内容传递

Error handling 错误处理

Lazy loading 懒加载

Debugging  调试

logging, tracing, profiling and monitoring 记录跟踪 优化 校准

Performance optimization 性能优化

Persistence  持久化

Resource pooling 资源池

Synchronization 同步

Transactions 事务


3、AOP动态代理:AOP代理(AOP Proxy): AOP框架创建的对象,包含通知。 在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。


4、静态AOP(包括静态织入)和动态AOP(包括动态代理、动态字节码生成、自定义类加载器、字节码转换)

     (1)静态织入:

                         a、原理:在编译期,切面直接以字节码形式编译到目标字节码文件中 ;

                         b、优点:对系统性能无影响; 

                         c、缺点:不够灵活;

     (2)动态代理 :

                       a、原理:在运行期,目标类加载后,为接口动态生成代理类。将切面织入到代理类中;

                       b、优点:更灵活;

                       c、缺点:切入的关注点要实现接口;

      (3)动态字节码生成:

                       a、原理:在运行期,目标类加载后,动态构建字节码文件生成目标类的子类,将切面逻辑加入到子类中;

                       b、优点:没有接口也可以织入;

                       c、缺点:扩展类的实例方法为final时,无法进行织入;

       (4)自定义类加载器:

                      a、原理:在运行期,目标加载前,将切面逻辑加到目标字节码里;

                      b、优点:可以对绝大部分类进行织入;

                      c、缺点:代码中若使用了其它类加载器,则这些类将不会被织入;

       (5)字节码转换

                      a、原理:在运行期,所有类加载器加载字节码前进行拦截;

                      b、优点:可以对所有类进行织入;


5、动态代理的实现           

                     

Java在JDK1.3后引入的动态代理机制,使我们可以在运行期动态的创建代理类。

使用动态代理实现AOP需要四个角色:被代理的类、被代理类的接口、织入器(Proxy.newProxyInstance())、InvocationHandler。织入器使用接口反射机制生成一个代理类,然后在这个代理类中织入代码(切入逻辑)。InvocationHandler是切面,包含了Advice和Pointcut

动态代理在运行期通过接口动态生成代理类。

              使用反射大量生成类文件可能引起Full GC造成性能影响,因为字节码文件加载后会 存放在JVM运行时区的方法区中(或持久代)。当方法区满的时候,会引起Full GC。因此当大量使用动态代理时,可以将持久代设置大一些,减少Full GC次数。

动态代理的核心其实就是代理对象的生成,即Proxy.newProxyInstance()。其中getProxyClass()方法用于获取代理类,主要做了三件事:在当前类加载器的缓存里搜索是否有代理类,没有则生成代理类并缓存在本地JVM里。

可以使用JD-GUI反编译软件打开jre\lib\rt.jar。



6、使用spring的AOP缺点:

a、只能对方法进行切入,不能对接口、属性、静态代码块进行切入(切入接口的某个方法,则该接口下所有实现类的该方法将被切入

b、同类中的互相调用方法将不会使用代理类。因为要使用代理类必须从spring容器中获取bean。



AOP各种的实现

AOP就是面向切面编程,我们可以从几个层面来实现AOP。

在编译器修改源代码,在运行期字节码加载前修改字节码或字节码加载后动态创建代理类的字节码,以下是各种实现机制的比较。 

 

类别

机制

原理

优点

缺点

静态AOP

静态织入

在编译期,切面直接以字节码的形式编译到目标字节码文件中。

对系统无性能影响。

灵活性不够。

动态AOP

动态代理

在运行期,目标类加载后,为接口动态生成代理类,将切面植入到代理类中。

相对于静态AOP更加灵活。

切入的关注点需要实现接口。对系统有一点性能影响。

动态字节码生成

在运行期,目标类加载后,动态构建字节码文件生成目标类的子类,将切面逻辑加入到子类中。

没有接口也可以织入。

扩展类的实例方法为final时,则无法进行织入。

自定义类加载器

在运行期,目标加载前,将切面逻辑加到目标字节码里。

可以对绝大部分类进行织入。

代码中如果使用了其他类加载器,则这些类将不会被织入。

字节码转换

在运行期,所有类加载器加载字节码前,前进行拦截。

可以对所有类进行织入。

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值