JDK自从1.3版本开始,就引入了动态代理,JDK的动态代理用起来非常简单,但是它有一个限制,就是使用动态代理的对象必须实现一个或多个接口 。如果想代理没有实现接口的类可以使用CGLIB包。
  CGLIB是一个强大的高性能的代码生成包。它被许多AOP的框架(例如Spring AOP)使用,为他们提供方法的interception(拦截)。Hibernate也使用CGLIB来代理单端single-ended(多对一和一对一)关联。EasyMock通过使用模仿(moke)对象来测试java代码的包。它们都通过使用CGLIB来为那些没有接口的类创建模仿(moke)对象。
  CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。

以下为模拟案例,在使用CGLIB时需引入cglib-nodep-2.1_3.jar包

定义一个HelloWorld类,注意此处是个类,而不是接口

package com.ljq.test;

/**
* 定义一个HelloWorld类
*
* @author jiqinlin
*
*/
public class HelloWorld {
public void sayHelloWorld() {
System.out.println("HelloWorld!");
}
}

CglibProxy类

package com.ljq.test;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; /**
* 通过Cglib实现在方法调用前后向控制台输出两句字符串
*
* @author jiqinlin
*
*/
public class CglibProxy implements MethodInterceptor {
//要代理的原始对象
private Object obj; public Object createProxy(Object target) {
this.obj = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.obj.getClass());// 设置代理目标
enhancer.setCallback(this);// 设置回调
enhancer.setClassLoader(target.getClass().getClassLoader());
return enhancer.create();
} /**
* 在代理实例上处理方法调用并返回结果
*
* @param proxy
* 代理类
* @param method
* 被代理的方法
* @param params
* 该方法的参数数组
* @param methodProxy
*/
public Object intercept(Object proxy, Method method, Object[] params,
MethodProxy methodProxy) throws Throwable {
Object result = null;
// 调用之前
doBefore();
// 调用原始对象的方法
result = methodProxy.invokeSuper(proxy, params);
// 调用之后
doAfter();
return result;
} private void doBefore() {
System.out.println("before method invoke");
} private void doAfter() {
System.out.println("after method invoke");
} }

测试类

package com.ljq.test;

public class HelloWorldTest {

    public static void main(String[] args) {
HelloWorld helloWorld=new HelloWorld();
CglibProxy cglibProxy=new CglibProxy();
HelloWorld hw=(HelloWorld)cglibProxy.createProxy(helloWorld);
hw.sayHelloWorld();
}
}

运行结果为:

Java动态代理(二)CGLIB动态代理应用的更多相关文章

  1. Java之代理(jdk静态代理,jdk动态代理,cglib动态代理,aop,aspectj)

    一.概念 代理是什么呢?举个例子,一个公司是卖摄像头的,但公司不直接跟用户打交道,而是通过代理商跟用户打交道.如果:公司接口中有一个卖产品的方法,那么公司需要实现这个方法,而代理商也必须实现这个方法. ...

  2. java的静态代理、jdk动态代理和cglib动态代理

    Java的代理就是客户端不再直接和委托类打交道,而是通过一个中间层来访问,这个中间层就是代理.使用代理有两个好处,一是可以隐藏委托类的实现:二是可以实现客户与委托类之间的解耦,在不修改委托类代码的情况 ...

  3. Java代理(静态代理、JDK动态代理、CGLIB动态代理)

    Java中代理有静态代理和动态代理.静态代理的代理关系在编译时就确定了,而动态代理的代理关系是在运行期确定的.静态代理实现简单,适合于代理类较少且确定的情况,而动态代理则给我们提供了更大的灵活性. J ...

  4. JDK动态代理和CGLib动态代理简单演示

    JDK1.3之后,Java提供了动态代理的技术,允许开发者在运行期间创建接口的代理实例. 一.首先我们进行JDK动态代理的演示. 现在我们有一个简单的业务接口Saying,如下: package te ...

  5. 【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理

    Spring AOP详解 . JDK动态代理.CGLib动态代理  原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspec ...

  6. 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。

    基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别. 我还是喜欢基于Schema风格的Spring事务管理,但也有很多人在用基于@Tras ...

  7. Spring -- <tx:annotation-driven>注解基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)的区别。

    借鉴:http://jinnianshilongnian.iteye.com/blog/1508018 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional ...

  8. Spring <tx:annotation-driven>注解 JDK动态代理和CGLIB动态代理 区别。

    基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别. 我还是喜欢基于Schema风格的Spring事务管理,但也有很多人在用基于@Tras ...

  9. JDK动态代理、CGLIB动态代理详解

    Spring的AOP其就是通过动态代理的机制实现的,所以理解动态代理尤其重要. 动态代理比静态代理的好处: 1.一个动态代理类可以实现多个业务接口.静态代理的一个代理类只能对一个业务接口的实现类进行包 ...

  10. jdk动态代理和cglib动态代理底层实现原理详细解析(cglib动态代理篇)

    代理模式是一种很常见的模式,本文主要分析cglib动态代理的过程 1. 举例 使用cglib代理需要引入两个包,maven的话包引入如下 <!-- https://mvnrepository.c ...

随机推荐

  1. bzoj3802: Vocabulary

    Description 给你三个字符串,这些字符串有些单词模糊不可认了,用"?"来代表. 现在你可以用任意英文小写字母来代表它们.要求是使得给定的三个字符串中 所有的"? ...

  2. <转--大话session>

    大话Session 原文地址:http://www.cnblogs.com/shoru/archive/2010/02/19/1669395.html 结语 到这里,读者应该对session有了更多的 ...

  3. POJ 1061 青蛙的约会(拓展欧几里得求同余方程,解ax+by=c)

    青蛙的约会 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 122871   Accepted: 26147 Descript ...

  4. [转]Java IDE 之 IntelliJ IDEA 2017

    参考链接1:http://blog.csdn.net/u012364631/article/details/47682011 IDEA Community(社区版) 使用Maven创建Web工程 并部 ...

  5. 处理DateTime.Now不经过ToString()转换的格式(带有AM、PM)问题

    问题是这样的: DateTime.Now不经过ToString()转换,网站部署到测试服务器(国内)得到的时间格式是:2018/8/17 16:26:09,而部署到国外服务器得到的时间格式是:17/8 ...

  6. webkit内核的浏览器为什么removeAttribute('style')会失效?

    做了一些研究,应该算是理清了问题. 首先,我们在这里常说的「属性」(attributes)其实分为两种:内容属性(content attributes)以及 IDL 属性(IDL attributes ...

  7. shell编程: 获得目录下(包括子目录)所有文件名,路径和文件大小

    转自:http://blog.chinaunix.net/uid-26000296-id-3575475.html function ergodic(){ ` do "/"$fil ...

  8. MPI 计时器函数 MPI_Wtime()

    ▶ 计时器函数 MPI_Wtime() 以及头文件 timer.h 中的宏函数 GET_TIME(),类似 time.h 中函数 clock() 的用法.注意 函数 clock() 记录的是CPU时间 ...

  9. Application.streamingAssetsPath

    [Application.streamingAssetsPath] This API contains the path to the StreamingAssets folder (Read Onl ...

  10. Hadoop Streaming:aggregate

    [Hadoop Streaming:aggregate] 1.实例1 测试文件test.txt mapper程序: 运行: $hadoop streaming -input /app/test.txt ...