Java动态代理
所谓代理,又分为静态代理和动态代理两种。在介绍动态代理之前,我们先了解下在Java中静态代理的使用方式和局限性。
假设当前我们有一个功能接口,需要通过代理类来调用该功能接口的实现类。我们可以使用静态代理调用的方式进行处理,在代理中可以执行额外的处理代码(如日志打印、执行时间的统计等等),代码如下:
/**
* 功能接口
*/
interface Duck {
void info();
void say();
}
/**
* 功能接口实现类
*/
class RealDuck implements Duck {
@Override
public void info() {
System.out.println("鸭子");
}
@Override
public void say() {
System.out.println("我是一只鸭子");
}
}
/**
* 代理类
*/
class DuckProxy implements Duck {
private Duck duck;
public DuckProxy(Duck duck) {
this.duck = duck;
}
@Override
public void info() {
System.out.println("调用前--->");
duck.info();
System.out.println("调用后--->");
}
@Override
public void say() {
System.out.println("调用前--->");
duck.say();
System.out.println("调用后--->");
}
}
public class TestStaticProxy {
public static void main(String[] args) {
// 创建被代理类对象
Duck realDuck = new RealDuck();
// 创建代理类对象,将通过该对象进行被代理类的调用
Duck duckProxy = new DuckProxy(realDuck);
// 调用代理类对象的方法,转而调用被代理类的方法
duckProxy.info();
// 同上
duckProxy.say();
}
}
以上,我们实现了一个静态代理。其存在一个弊端:假设要增加另外的一个接口则需要一个与之配对的另一个代理,这样会导致类的爆炸。。。此时我们可以引入动态代理来规避此类问题,减少代码的冗余
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @author luhuancheng
* @since 2018/2/8 23:15
*/
interface Human {
void info();
void say();
}
/**
* 被代理类
*/
class SuperMan implements Human {
@Override
public void info() {
System.out.println("超人来了......");
}
@Override
public void say() {
System.out.println("我是超人......");
}
}
/**
* 日志工具
*/
class LogUtils {
public static void before() {
System.out.println("调用前时间" + System.currentTimeMillis());
}
public static void after() {
System.out.println("调用后时间" + System.currentTimeMillis());
}
}
class MyInvocationHandler implements InvocationHandler {
private Object object;
public void setObject(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
LogUtils.before();
Object result = method.invoke(object, args);
LogUtils.after();
return result;
}
}
class MyProxy {
public static Object getProxy(Object object) {
MyInvocationHandler handler = new MyInvocationHandler();
handler.setObject(object);
// 返回一个代理类对象。该代理类实现了与对象object一致的接口。
// 并且在调用该代理类对象的相关方法时,转而调用其 invoke(Object proxy, Method method, Object[] args)方法;
// 实现了对模版代码的重用,并且避免了代理类与被代理类必须成对存在的弊端
return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), handler);
}
}
public class TestDynamicProxy {
public static void main(String[] args) {
SuperMan superMan = new SuperMan();
Object object = MyProxy.getProxy(superMan);
Human man = (Human) object;
man.info();
man.say();
}
}
posted on 2018-02-08 23:48 luhuancheng1992 阅读(152) 评论(0) 收藏 举报
浙公网安备 33010602011771号