Java动态代理(JDK和Cglib)
动态代理
代理模式,是为其他对象提供一个代理来控制对某个真实对象的访问。代理类负责对调用的消息进行处理和转发,以及在委托类执行后的一些后续操作的处理。代理类似一个演员的经纪人,负责对所有的活动进行筛选和过滤,并且将消息转发给该演员,在演员演出后,负责做一些收尾工作。
动态代理,它在静态代理的基础上又迈进了一步。可以动态的创建代理,并且动态的处理对所代理方法的调用。动态代理则分为以下两种:
- 1、JDK动态代理:
- 基于接口进行代理 (必须实现接口)
- 2、Cglib动态代理:
- 基于继承进行代理 原理为继承要代理的类,并Override其中的方法实现代理
JDK动态代理
动态代理的使用方法如下:
- 实现InvocationHandler完成自己的调用处理器
- 通过Proxy.newProxyInstance()来创建动态代理,该方法需要的到三个参数,
- 一个类加载器(可从已被加载的对象中获取)
- 代理实现的接口列表
- 以及InvocationHandler接口的一个实现,并传递给处理器一个实际对象。
- 通过代理对象来调用请求
这样,外部的所有调用请求,就都会重定向到调用处理器,在经过处理器的调用,通过Method.invoke()转发给委托对象。这样就可以简单实现了对方法调用的拦截和过滤。
/**
* 定义一个接口并实现
*/
interface Interface {
void doSomething();
}
class Real implements Interface {
public void doSomething(String arg) {
Sytstem.out.println("dosomething " + arg);
}
}
import java.lang.reflect.*;
/**
* 实现InvocationHandler接口
* 完成自定义的调用处理器
*/
class MyProxyHandler implements InvocationHandler {
//被代理对象
private Object proxied;
public MyProxyHandler(Object proxied) {
this.proxied = proxied;
}
public Object invoke(Object object, Method method, Object[] args)
throws Throwable {
System.out.println("****before:" + method + "****");
method.invoke(proxied, args);
System.out.println("****after:" + method + "****");
}
}
/**
* 通过Proxy.newProxyInstance()方法获取动态代理
* 使用代理调用方法
*/
class DynamicProxy {
public static void main(String[] args) {
Real real = new Real();
Interface proxy = (Interface)Proxy.newProxyInstance(
Interface.class.getClassLoader(),
new Class[]{ Interface.class },
new MyProxyHandler(real);
)
proxy.doSomething("hello");
}
}
Cglib动态代理
Chlib动态代理使用主要有如下几点:
- 实现MethodInterceptor,完成拦截的切面处理
- 通过methodProxy.invokeSuper(obj, args);来调用被代理的方法
- 通过实例化的Enhancer生成代理对象,实例化步骤如下:
- 实例化Enhancer:Enhancer enhancer = new Enhancer();
- 设置被代理的基类:enhancer.setSuperClass(clz);
- 设置回调函数,即是实现的切面:enhancer.setCallback(methodInterceptor);
- 创建代理对象:enhancer.create();
- 使用生成的代理对象完成调用
public class MyInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("#####before######");
Object result = null;
try {
result = methodProxy.invokeSuper(o, objects);
} catch (Throwable e) {
System.out.println(e.getMessage());
throw e;
}
System.out.println("#####after#####");
return result;
}
public static void main(String[] args) {
BaseObject proxyObj = (BaseObject)getProxyObj(RealObject.class, new MyInterceptor());
proxyObj.method();
}
public static Object getProxyObj (Class clz, MethodInterceptor callback) {
Enhancer enhancer = new Enhancer();
return enhancer.create(clz, callback);
}
}
abstract class BaseObject {
public abstract void method();
}
class RealObject extends BaseObject {
@Override
public void method() {
System.out.println("real obj was called!!!");
}
}