http://blog.csdn.net/yerenyuan_pku/article/details/52864395

使用CGLIB实现AOP功能

在Java里面,我们要产生某个对象的代理对象,这个对象必须要有一个特点,即这个对象必须实现一个接口,动态代理技术只能基于接口进行代理。有时候我们在做开发的时候,这个对象就没有实现接口,有人可能会说,它既然没有接口,那我就给它定义一个接口,这是不行的,因为有时候我们拿到一个对象,而这个对象是服务器产生给我们的,是服务器提供给我们的,又不是我们自己写的,动不动就给它定义一个接口,给它找个爸爸,哪那行呢?但我们现在要对它进行增强,这时用动态代理技术就不行了,动态代理技术只能是基于接口,那如果这个对象没有接口,又该怎么做呢? 
那这时我们就需要使用另外一套API——CGLIB了,这套API,即使没有接口,它也可以帮我们产生这个对象的代理对象。它的内部是怎么去产生这个对象的代理对象的呢?——实际上产生的是这个对象的子类,也即我们把一个对象交给CGLIB,它返回出来的似乎是一个代理对象(但它不是要产生一个对象的代理对象),但其实这个代理对象就是这个对象的子类,利用子类的方式来创建代理对象。在Spring里面就是这样做的,Spring里面有一个AOP编程(即面向切面编程,说白了就是动态代理,我们经常会交给Spring一个对象,它就会返回代理对象给我们,它在返回代理对象的时候,首先会检查我们这个对象有没有实现一个接口,如果我们这个类有接口,它使用Java的动态代理技术来帮我们构建出代理对象;如果我们这个类没有实现接口,它会使用CGLIB这套API,采用创建子类的方式来创建代理对象)。 
本文是建立在使用JDK中的Proxy技术实现AOP功能的案例的基础之上的,若要使用CGLIB这套API实现AOP功能,就要将其所需要的jar包导入项目中,所需的jar包有:

  • asm-2.2.3.jar
  • cglib-nodep-2.2.jar

首先将PersonServiceBean类的代码修改为:

public class PersonServiceBean {private String user = null;public String getUser() { return user; } public PersonServiceBean() {} public PersonServiceBean(String user) { this.user = user; } public void save(String name) { System.out.println("我是save()方法"); } public void update(String name, Integer personid) { System.out.println("我是update()方法"); } public String getPersonName(Integer personid) { System.out.println("我是getPersonName()方法"); return "xxx"; } }

可发现PersonServiceBean类没实现一个接口,现在要想产生PersonServiceBean类的代理对象,这时就不能不使用CGLIB这套API了。 
我们在it.cast.aop包下新建一个类——CGlibProxyFactory.java,与JDKProxyFactory类相似,都用于创建代理对象,其代码为:

public class CGlibProxyFactory implements MethodInterceptor { private Object targetObject; // 代理的目标对象 public Object createProxyInstance(Object targetObject) { this.targetObject = targetObject; Enhancer enhancer = new Enhancer(); // 该类用于生成代理对象 enhancer.setSuperclass(this.targetObject.getClass()); // 设置目标类为代理对象的父类 enhancer.setCallback(this); // 设置回调用对象为本身 return enhancer.create(); } @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { PersonServiceBean bean = (PersonServiceBean)this.targetObject; Object result = null; if (bean.getUser() != null) { // 有权限 result = methodProxy.invoke(targetObject, args); // 把方法调用委派给目标对象 } return result; } }
  • 1

结论:CGLIB可以生成目标类的子类,并重写父类非final修饰符的方法。 
接着就要修改AOPTest类的代码了,我们先将AOPTest类的代码改为:

public class AOPTest {@Test public void proxyTest() { JDKProxyFactory factory = new JDKProxyFactory(); PersonService service = (PersonService) factory.createProxyInstance(new PersonServiceBean()); service.save("888"); } @Test public void proxyTest2() { CGlibProxyFactory factory = new CGlibProxyFactory(); PersonServiceBean service = (PersonServiceBean) factory.createProxyInstance(new PersonServiceBean("xxx")); service.save("999"); } }
  • 1
  • 2

测试proxyTest2()方法,Eclipse控制台会打印: 
 
若是将AOPTest类的代码改为:

public class AOPTest {@Test public void proxyTest() { JDKProxyFactory factory = new JDKProxyFactory(); PersonService service = (PersonService) factory.createProxyInstance(new PersonServiceBean()); service.save("888"); } @Test public void proxyTest2() { CGlibProxyFactory factory = new CGlibProxyFactory(); PersonServiceBean service = (PersonServiceBean) factory.createProxyInstance(new PersonServiceBean()); service.save("999"); } }
  • 1

再次测试proxyTest2()方法,Eclipse控制台什么都不会打印。 
如要查看源码,可点击使用JDK中的Proxy技术实现AOP功能与使用CGLIB实现AOP功能进行下载。

AOP概念解释

AOP用在哪些方面:AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任,例如事务处理、日志管理、权限控制,异常处理等,封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。

AOP中的概念

Aspect(切面):指横切性关注点的抽象即为切面,它与类相似,只是两者的关注点不一样,类是对物体特征的抽象,而切面是横切性关注点的抽象。 
joinpoint(连接点):所谓连接点是指那些被拦截到的点(可以是方法、属性、或者类的初始化时机(可以是Action层、Service层、dao层))。在Spring中,这些点指的是方法,因为Spring只支持方法类型的连接点,实际上joinpoint还可以是field或类构造器。 
Pointcut(切入点):所谓切入点是指我们要对那些joinpoint进行拦截的定义,也即joinpoint的集合。 
Advice(通知):所谓通知是指拦截到joinpoint之后所要做的事情就是通知。通知分为前置通知、后置通知、异常通知、最终通知、环绕通知。我们就以CGlibProxyFactory类的代码为例进行说明:

public class CGlibProxyFactory implements MethodInterceptor { private Object targetObject; // 代理的目标对象 public Object createProxyInstance(Object targetObject) { this.targetObject = targetObject; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.targetObject.getClass()); // 设置目标类为代理对象的父类 enhancer.setCallback(this); return enhancer.create(); } // 从另一种角度看: 整个方法可看作环绕通知 @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { PersonServiceBean bean = (PersonServiceBean)this.targetObject; Object result = null; if (bean.getUser() != null) { // 有权限 // ...... advice() ----> 前置通知(所谓通知,就是我们拦截到业务方法之后所要干的事情) try { result = methodProxy.invoke(targetObject, args); // 把方法调用委派给目标对象 // ...... afteradvice() ----> 后置通知 } catch (RuntimeException e) { // ...... exceptionadvice() ----> 异常通知 } finally { // ...... finallyadvice() ----> 最终通知 } } return result; } }

Target(目标对象):代理的目标对象。 
Weave(织入):指将aspects应用到target对象并导致proxy对象创建的过程称为织入。 
Introduction(引入):在不修改类代码的前提下,Introduction可以在运行期为类(代理类)动态地添加一些方法或Field。 
AOP带来的好处:降低模块的耦合度;使系统容易扩展;更好的代码复用性

(转)使用CGLIB实现AOP功能与AOP概念解释相关推荐

  1. 从零开始实现一个简易的Java MVC框架(六)--加强AOP功能

    前言 在前面从零开始实现一个简易的Java MVC框架(四)--实现AOP和从零开始实现一个简易的Java MVC框架(五)--引入aspectj实现AOP切点这两节文章中已经实现了AOP功能并且引用 ...

  2. uni中动态加载class_SpringBoot中使用LoadTimeWeaving技术实现AOP功能

    1. 关于LoadTimeWeaving 1.1 LTW与不同的切面织入时机 AOP--面向切面编程,通过为目标类织入切面的方式,实现对目标类功能的增强.按切面被织如到目标类中的时间划分,主要有以下几 ...

  3. Spring AOP功能和目标

    1.AOP的作用 在OOP中,正是这种分散在各处且与对象核心功能无关的代码(横切代码)的存在,使得模块复用难度增加.AOP则将封装好的对象剖开,找出其中对多个对象产生影响的公共行为,并将其封装为一个可 ...

  4. SpringBoot 使用AOP功能

    RPC,AOP都会用到代理,代理的技术有jdk的Proxy代理(必须实现接口),cglib(可以不实现接口,直接实现类),Javassist(jboss )而Spring boot本身也在方方面面使用 ...

  5. Spring AOP 功能使用详解

    前言 AOP 既熟悉又陌生,了解过 Spring 人的都知道 AOP 的概念,即面向切面编程,可以用来管理一些和主业务无关的周边业务,如日志记录,事务管理等:陌生是因为在工作中基本没有使用过,AOP ...

  6. 采用Spring实现AOP功能

    1.AOP中的概念 Aspect(切面):指横切性关注点的抽象即为切面,它与类相似,只是两者的关注点不一样,类是对物体特征的抽象,而切面横切性关注点的抽象. joinpoint(连接点):所谓连接点是 ...

  7. Spring源码分析之ProxyFactoryBean方式实现Aop功能的分析

    实现Aop功能有两种方式, 1. ProxyFactoryBean方式: 这种方式是通过配置实现 2. ProxyFactory方式:这种方式是通过编程实现 这里只说ProxyFactoryBean方 ...

  8. 使用AspectJ注解技术实现AOP功能

    AspectJ是一个面向切面编程的框架,使用AspectJ不需要改动Spring配置文件,就可以实现Spring AOP功能.本篇结合实际案例详细讲述使用AspectJ实现AOP功能.通过本篇的学习, ...

  9. (转)使用JDK中的Proxy技术实现AOP功能

    http://blog.csdn.net/yerenyuan_pku/article/details/52863780 AOP技术在企业开发中或多或少都会用到,但用的最多的大概就是做权限系统时,在做权 ...

最新文章

  1. 太强了,Python 开发桌面小工具,让代码替我们干重复的工作~
  2. 如何快速学习Java?
  3. 是什么浪费了我的时间
  4. 【ros】1.ros的安装
  5. 用Python Pandas处理亿级数据
  6. 深度 | 一条查询SQL的前世今生 —— ClickHouse 源码阅读
  7. java中6左移2怎么算_(六)Java中的按位运算
  8. Hibernate学习系列————注解一对多单向实例
  9. Ubuntu 安装Wireshark
  10. ECMAScript面向对象(一)
  11. Kubernetes网络方案的三大类别和六个场景
  12. Oracle学习VII —— Oracle建表
  13. 如何用wps画三线图(最方便最快的方法)
  14. Captin for mac(大小写切换悬浮窗提示)
  15. 数字贸易标准体系框架
  16. openwrt 中 Luci 的简单使用
  17. 账号注册及登录具体流程
  18. windows下,查看apk的包名、以及查找appActivity(aapt命令)
  19. 简洁的PHP图床源码烟雨图床程序源码
  20. Linux 下后台运行程序,查看和关闭后台运行程序

热门文章

  1. Twisted twisted.python.log日志
  2. SQL注入学习资料总结
  3. 汇编语言:编写code段中代码,将a段和b段中的数据依次相加,将结果放到c段
  4. USACO(含training section)水题合集[5/未完待续]
  5. 从起源到未来:能自己编程和改进的超人工智能会出现吗?
  6. 从用户不足2000万到27亿,这项技术真要上天了?
  7. asp sql 导出 excel_Mysql数据导出到excel基于python
  8. 说说我在制造业大厂当了一个月程序员的感受
  9. 超干货 | 这些概念可是操作系统的灵魂,你弄懂了几个?
  10. 一上来,就问原理,问上亿(MySQL)大表的索引优化,我的天...