java Proxy代理&cglib代理
2016-07-07 15:30
309 查看
一、java原生代理
1、代理概念介绍
为某个对象提供一个代理,以控制对这个对象的访问。 代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理 对象替代。代理类负责请求的预处理、过滤、将请求分派给委托类处理、以及委托类执行 完请求后的后续处理。
2、代理分类
java代理分为两类,静态代理和动态代理。静态代理通过代码的编写,生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。
动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。
3、动态代理示例
使用java.lang.reflect.Proxy进行创建
3.1 接口部分
使用Proxy创建代理,必须预先定义接口package wang.conge.javasedemo.core.proxy; public interface HelloService { public String sayHello(String name); }
3.2 业务实现部分
package wang.conge.javasedemo.core.proxy; public class HelloServiceImpl implements HelloService { @Override public String sayHello(String name) { return "hello:" + name; } }
3.3 代理业务部分
package wang.conge.javasedemo.core.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class HelloInvocationHandler implements InvocationHandler{ private Object delegate; public HelloInvocationHandler(Object delegate){ this.delegate = delegate; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("invoke"); return method.invoke(this.delegate, args); } }
3.4 测试代码
package wang.conge.javasedemo.core.proxy; import java.lang.reflect.Proxy; public class JavaProxyTest { public static void main(String[] args) { HelloInvocationHandler invocationHandler = new HelloInvocationHandler(new HelloServiceImpl()); HelloService helloService = (HelloService) Proxy.newProxyInstance(HelloService.class.getClassLoader(), new Class[] { HelloService.class }, invocationHandler); System.out.println(helloService.sayHello("conge")); } }
运行结果
invokehello:conge
3.5 Proxy代理总结
用法总结:主要使用java.lang.reflect.Proxy 进行创建代理类 主要方法:public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h); 第一个参数是ClassLoader,也即是加载所要代理类的相应的ClassLoader 第二个参数是interfaces,即是所要代理类的接口 第三个参数是代理业务部分,需要实现InvocationHandler接口
优缺点总结:
优点: 1、可以替代java静态代理,集中式处理 缺点: 1、所代理的类,必须预先定义接口,不能直接没有定义接口的类 2、所代理的接口也必须是public类型,如果是package ,必须在访问包的顶层目录
二、Cglib代理
因为Proxy不能代理没有定义接口的类,缺陷比较大。但还有另外一个方案可以解决这个问题。cglib。1.cglib介绍
cglib简述 Cglib是一个优秀的动态代理框架,它的底层使用ASM在内存中动态的生成被代理类的子类,使用CGLIB即使代理类没有实现任何接口也可以实现动态代理功能。CGLIB具有简单易用,它的运行速度要远远快于JDK的Proxy动态代理: 使用CGLIB需要导入以下两个jar文件: $1: asm.jar – CGLIB的底层实现 $2: cglib.jar – CGLIB的核心jar包。 CGLIB的核心类: net.sf.cglib.proxy.Enhancer – 主要的增强类 net.sf.cglib.proxy.MethodInterceptor – 主要的方法拦截类,它是Callback接口的子接口,需要用户实现 net.sf.cglib.proxy.MethodProxy – JDK的Java.lang.reflect.Method类的代理类,可以方便的实现对源对象方法的调用,如使用: Object o = methodProxy.invokeSuper(proxy, args);//虽然第一个参数是被代理对象,也不会出现死循环的问题。
2.使用cglib进行代理
2.1 所依赖cglib
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.2.2</version></dependency>
2.2 业务服务
还是使用java原生代理的HelloServiceImpl , see 原生代理3.2
2.3 代理业务部分
package wang.conge.javasedemo.core.cglib; import java.lang.reflect.Method; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class HelloCglibHandler implements MethodInterceptor { private Object delegate; public HelloCglibHandler(Object delegate){ this.delegate = delegate; } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("intercept"); return method.invoke(delegate, args); } }
2.4 测试代码
package wang.conge.javasedemo.core.cglib; import net.sf.cglib.proxy.Enhancer; import wang.conge.javasedemo.core.proxy.HelloServiceImpl; public class EnhancerTest { public static void main(String[] args) { HelloCglibHandler cglibHandler = new HelloCglibHandler(new HelloServiceImpl()); Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(HelloServiceImpl.class); enhancer.setCallback(cglibHandler); HelloServiceImpl helloService = (HelloServiceImpl) enhancer.create(); System.out.println(helloService.sayHello("conge")); } }
运行结果:
intercepthello:conge
2.5 cglib代理总结
主要使用Enhancer进行创建代理类,可以直接对类进行代理,运行速度也比原生代理要快。
相关文章推荐
- JDK动态代理VS CgLib
- MySQL Proxy(解决注入的另一思路)
- mysql proxy问题的解决方法
- Win2003 WinHTTP Web Proxy Auto-Discovery Service 导致的服务器重启
- java动态代理和cglib动态代理示例分享
- use jscript with List Proxy Server Information
- MySQL Proxy的安装及基本命令使用教程
- Ubuntu10下如何搭建MySQL Proxy读写分离探讨
- node-http-proxy修改响应结果实例代码
- WinHTTP Web Proxy Auto-Discovery Service 服务处于停止状态
- 实例解析jQuery中proxy()函数的用法
- java动态代理(jdk与cglib)详细解析
- 基于zbus的MySQL透明代理(<100行)
- zabbix 分布式部署
- java动态代理模式
- AOP切面编程
- CGLIB代理就这么简单
- proxychains-ng 工作原理分析
- 如何用Go语言打造一个高性能MySQL Proxy