前面说到了java的动态代理,但是动态代理依赖于接口,这次来看看cglib来实现的代理...

假设有如下方法,这回没有说接口哦~

package proxy.cglibProxy;

public class RealSubject2 {

public void request() {
System.out.println("request...");
}

public void response() {
System.out.println("response...");
}

}

然后,需求来了,希望在执行方法前后加某个其他的操作,这个类没有实现任何接口啊,不能用动态代理了,只好使用cglib了

那么可以这么做:

package proxy.cglibProxy;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
* 使用cglib动态代理
*
*
*/
public class CglibProxy implements MethodInterceptor {
private Object target;

/**
* 创建代理对象
*
* @param target
* @return
*/
public Object getInstance(Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
// 回调方法
enhancer.setCallback(this);
// 创建代理对象
return enhancer.create();
}

// 回调方法
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("before...");
proxy.invokeSuper(obj, args);
System.out.println("afeter...");
return null;
}

}

然后客户端代码可以这么写:

package proxy.cglibProxy;

public class CglibTestMain {

public static void main(String[] args) {
CglibProxy cglib = new CglibProxy();
RealSubject2 subject = (RealSubject2) cglib.getInstance(new RealSubject2());
subject.request();
}

}

如果我们在上面的main方法里面加一行:

System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"c:\\cglib");

就可以看到编译后的class,你会发现一个RealSubject2$$EnhancerByCGLIB$$d705369d.class

用反编译工具打开看看你就明白了:(这里推荐一个小巧的反编译工具,点我下载 )

public class RealSubject2$$EnhancerByCGLIB$$d705369d extends RealSubject2
implements Factory
{
......
}

也就是说,cglib其实通过修改字节码,给没有实现接口的RealSubject2设置了一个继承它的子类....

java代理-cglib的更多相关文章

  1. 【Java入门提高篇】Day12 Java代理——Cglib动态代理

    今天来介绍另一种更为强大的代理——Cglib动态代理. 什么是Cglib动态代理? 我们先回顾一下上一篇的jdk动态代理,jdk动态代理是通过接口来在运行时动态创建委托类的代理对象,但是跟静态代理一样 ...

  2. java代理的深入浅出(二)-CGLIB

    java代理的深入浅出(二)-CGLIB 1.基本原理 CGLIB的原理就是生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法.在子类中拦截所有父类方法的调用,拦截下来交给设置的Me ...

  3. Java代理(静态/动态 JDK,cglib)

    Java的代理模式是应用非常广泛的设计模式之一,也叫作委托模式,其目的就是为其他的对象提供一个代理以控制对某个对象的访问和使用,代理类负责为委托类预处理消息,过滤消息并转发消息,以及对消息执行后续处理 ...

  4. java 代理模式(静态代理、动态代理、Cglib代理) 转载

    Java的三种代理模式 1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩 ...

  5. 浅谈Java代理二:Cglib动态代理-MethodInterceptor

    浅谈Java代理二:Cglib动态代理-MethodInterceptor CGLib动态代理特点: 使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生 ...

  6. Java静态代理&动态代理&Cglib代理详解

    一.静态代理 根据被代理的类的时机的不同,如果在编译阶段就能确定下来的被代理的类是哪一个,那么,就可以使用静态代理的方式. 申明一个接口: /** * @author jiaqing.xu@hand- ...

  7. java代理,静态代理、jdk代理、cglib代理、Aspectj

    我实在接触spring的时候才接触到代理这个东西的,一直想整理一下笔记. 什么是代理模式:代理模式是通过代理对象访问目标对象,这样可以在目标对象基础上增强额外的功能.简单来说就是要创建一个新的对象,我 ...

  8. Java代理:静态代理、JDK动态代理和CGLIB动态代理

    代理模式(英语:Proxy Pattern)是程序设计中的一种设计模式.所谓的代理者是指一个类别可以作为其它东西的接口.代理者可以作任何东西的接口:网络连接.存储器中的大对象.文件或其它昂贵或无法复制 ...

  9. java反射 cglib asm相关资料

    有篇文章对java反射的调用的效率做了测试,写的比较好.猛击下面地址 http://www.blogjava.net/stone2083/archive/2010/09/15/332065.html ...

随机推荐

  1. Android-有序广播

    在之前的博客,Android-广播概念,中介绍了(广播和广播接收者)可以组件与组件之间进行通讯,有两种类型的广播(无序广播 和 有序广播),这篇博客就来讲解有序广播的代码实现: 有序广播:接收者 可以 ...

  2. [Postgres]Postgres复制表

    在需要把含有分表的总表备份的时候想到的笨办法,如果有什么更先进的办法万望告知. 比如TableOld是由TableOld1,TableOld2,TableOld3组合而成,现在需要对TableOld进 ...

  3. 配置IIS Express,支持JSON

    方法有2种: 1. 命令行 a. cd "iis express的安装目录"  例如:cd C:\Program Files (x86)\IIS Express b. appcmd ...

  4. ubuntu16.04系统精简

    ubuntu16.04系统精简 一.更新系统 apt-get update apt-get dist-upgrade 二.查看所有内核 sudo dpkg --get-selections |grep ...

  5. SQL SERVER 查找锁信息

    通过系统的存储过程  sp_who 或 sp_who2 可以查找出所有的锁信息, 但是看不出是哪个表, 什么语句 当使用 sp_who 或 sp_who2 查找锁信息的时候, 有个 spid 信息,  ...

  6. WP8中使用async/await扩展HttpWebRequest

    前文讲到WP8中使用Async执行HTTP请求,用了微软提供的扩展.下面提供了一种方法,自己实现HttpWebRequest的扩展. 随后就可以使用 await HttpWebRequest.GetR ...

  7. 弹性盒子模型display:flex

    1.div上下左右居中 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...

  8. BZOJ 1426--收集邮票(概率与期望&DP)

    1426: 收集邮票 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 504  Solved: 417[Submit][Status][Discuss] ...

  9. PHP开始1 php的命名规范

    常量 php 中有一些预定义常量,我们常常称他们为'魔术常量'. __LINE__          返回文件中的当前行号 __FILE__           返回该文件的完整路径和文件名 __DI ...

  10. ubuntu下apache2使用的简单总结

        一. 修改apache2原80端口为90端口 1. 修改/etc/apache2/ports.conf, 将端口80改为90,443,改为444 2. 修改/etc/apache2/sites ...