您的位置:首页 > 编程语言 > Java开发

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进行创建代理类,可以直接对类进行代理,运行速度也比原生代理要快。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Proxy cglib