返回信息流引子
今天呢,我们将用Proxy类来制作一个嘴贱的代理类。
首先看一下proxy类的简单用法:
Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。
创建某一接口 Foo 的代理:
InvocationHandler handler = new MyInvocationHandler(...);
Class proxyClass = Proxy.getProxyClass(
Foo.class.getClassLoader(), new Class[] { Foo.class });
Foo f = (Foo) proxyClass.
getConstructor(new Class[] { InvocationHandler.class }).
newInstance(new Object[] { handler });
或使用以下更简单的方法:
Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
new Class[] { Foo.class },
handler);
更详细参考reference;
具体操作
我们需要定义InvocationHandler,这个类是代理的核心,它会将操作分配到具体的Method上,代理会随机挑选一句话输出。
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
public class BlaBlaProxy implements InvocationHandler{
//目标类
private Object target;
public BlaBlaProxy(Object target) {
this.target = target;
}
private Random random = new Random(47);
//要输出的话
private String[] sentnces = new String[]{
"this method is a shit.",
"your code tasted like a shit.",
"你的代码可以让你升任CEO,走上人生巅峰.",
"你看来不适合做码农.",
"这个代码只有上帝能看懂。",
"你是个好人~但是不适合写代码。",
"世界太大,你该出去走走。"
};
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//根据不同的方法输出不同话
StringBuilder builder = new StringBuilder();
builder.append(method.getName()).append("->")
.append(sentnces[random.nextInt(sentnces.length)]);
Object o = method.invoke(target, args);
System.out.println(builder.toString());
return o;
}
public static void main(String[] args) {
LinkedList<Integer> list = new LinkedList<>();
List<Integer> integers = (List<Integer>) Proxy.newProxyInstance(list.getClass().getClassLoader(),
new Class[]{List.class}, new BlaBlaProxy(list));
integers.add(11);
integers.clear();
integers.hashCode();
integers.add(111);
integers.get(0);
integers.isEmpty();
integers.listIterator();
}
}
接下来看看黑科技的力量
output:
add->世界太大,你该出去走走。
clear->你的代码可以让你升任CEO,走上人生巅峰.
hashCode->世界太大,你该出去走走。
add->your code tasted like a shit.
get->你是个好人~但是不适合写代码。
isEmpty->你的代码可以让你升任CEO,走上人生巅峰.
listIterator->this method is a shit.
其实吧,proxy真正的用法可以是AOP。
这是一条镜像帖。来源:北邮人论坛 / java / #40063同步于 2015/4/18
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
黑科技-自定义嘴贱Proxy
sgoal
2015/4/18镜像同步8 回复
订阅后,新回复会通过你的通知中心匿名送达。
8 条回复
思想是一样的。最终的代码应该也很相似。
做AOP-面向切面编程。假如有多个Webservice的接口都需要打log和auth, 就可以把log和auth的代码写到一个‘切面’中去然后用proxy的方式加到多个接口上。
其实模板模式也可以实现类似的功能。
public abstract class Template{
public void invoke(){
doLog();
doAuth();
invokeLogic();
donothing();
}
protected abstract void invokeLogic();
private void doLog(){
...
}
...
}
然后子类继承了之后只实现invokeLogic就行。
【 在 icyfox 的大作中提到: 】
: 这个Proxy和Proxy的设计模式是什么关系~?
这个算是代理模式吧,与原来的类有相同的接口,为原来的类添加了一些功能~
【 在 icyfox 的大作中提到: 】
: 这个Proxy和Proxy的设计模式是什么关系~?
是的~就是这样
【 在 aiquestion 的大作中提到: 】
: 思想是一样的。最终的代码应该也很相似。
: 做AOP-面向切面编程。假如有多个Webservice的接口都需要打log和auth, 就可以把log和auth的代码写到一个‘切面’中去然后用proxy的方式加到多个接口上。
: 其实模板模式也可以实现类似的功能。
: ...................