java代理模式分为静态代理和动态代理
说说他们的优缺点:
静态代理:能够实现精准操作,相对代码也少点,但是可扩展性很低
动态代理:相对于静态代理,代码相对多一点,但是可扩展性比较好。
我这里使用的是动态代理
一、什么时候使用动态代理?
如果你要写一个框架,返回结果是一定的,但是你的代码不一定能满足所有人的业务逻辑要求,你就可以使用动态代理,不管他中间怎么操作,怎么变化你的结果最终不会变化。
二、实现思路
首先定义需要代理的接口,并且实现接口中的方法,然后实现 InvocationHandler 接口,最后在调用处 使用Proxy.newProxyInstance 得到接口的实例,最后调用实现方法
三、实现
1、创建接口类
public interface Speak {
void say();
}
2、实现接口
public class RealSpeak implements Speak{
public void say() {
System.out.println("我是真正讲话的方法");
}
}
3、实现 InvocationHandler
public class MyIncationHandler implements InvocationHandler {
/**
* 真实对象类型
*/
private Object target;
public MyIncationHandler(Object target) {
this.target = target;
}
/**
* 调用invoke
*/
public Object invoke(Object obj, Method method, Object[] args)
throws Throwable {
System.out.println("before");
Object result = method.invoke(target, args);
System.out.println("after");
return result;
}
}
4、调用
public class Test {
public static void main(String[] args) {
Speak speak = new RealSpeak();
MyIncationHandler myIncationHandler = new MyIncationHandler(speak);
/**
* 第一个参数 classLoader contextLoader
* 第二个参数 接口数组 决定着返回的对象实现了哪些接口
* 第三个参数 myIncationHandler 代理时 需要处理具体的操作
*/
Speak testSpeak = (Speak) Proxy.newProxyInstance(Thread.currentThread()
.getContextClassLoader(), speak.getClass().getInterfaces(),
myIncationHandler);
testSpeak.say();
}
}
注意,代码中的 Proxy.newProxyInstance、和 InvocationHandler属于java.lang.reflect的包下