代理模式
-------------------------------代理模式-------------------------------
使用条件: 在一个类的某些方法上 增加一些 额外操作.
优点: 1.不用修改 原来类的源代码,只需要在加一个类作为中间层增加新的操作.
2.解耦
静态代理:
-由程序员创建代理类或特定工具自动生成源代码再对其编译。在程序运行前代理类的.class文件就已经存在了
思路:
一个代理类,(原来类)
一个委托类,(中间层)
他们继承同一个接口.
接口中写有需要增加新操作的方法.
通过 调用委托类,用来调用代理类,在委托类调用代理类的方法中增加新操作
就完成了静态代理
缺点:
(1)由于委托类和代理类使用同一个接口,接口一旦改动,所有是实现类都需要更改.
(增加代码维护复杂度)
(2)代理对象只服务于一种对象,下面代码只为 Interface 提供了一种代理类,如果还有其他类型的对象,那么就要提供更多的代理类.
比如: 如果要为 OtherInterface 提供代理,我们还要创建一种代理 OtherInterface 的代理类
即静态代理类只能为特定的接口(Service)服务。如想要为多个接口服务则需要建立很多个代理
类。
(不适合规模较大的程序)
import java.lang.reflect.Method;
interface Interface{
void doSomething();
void somethingElse(String arg);
}
class RealObject implements Interface{
public void doSomething() {
System.out.println("Do something");
}
public void somethingElse(String arg) {
System.out.println("something " + arg);
}
}
class SimpleProxy implements Interface{
private Interface proxied;
public SimpleProxy(Interface proxied) {
this.proxied = proxied;
}
public void doSomething() {
System.out.println("SimpleProxy dosomething");
proxied.doSomething();
}
public void somethingElse(String arg) {
System.out.println("SimpleProxy " + arg);
proxied.somethingElse(arg);
}
}
public class Test{
public static void consumer(Interface iface) {
iface.doSomething();
iface.somethingElse("args");
}
public static void main(String[] args) throws ClassNotFoundException {
consumer(new RealObject());
consumer(new SimpleProxy(new RealObject()));
}
}
---输出:
Do something
something args
SimpleProxy dosomething
Do something
SimpleProxy args
something args
为了解决静态代理的缺点,我们需要一个代理类完成全部的代理功能.
那么就出现了动态代理:
动态代理
-在程序运行时运用反射机制动态创建而成
import java.awt.image.RescaleOp;
import java.lang.reflect.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
interface Interface{
void doSomething();
void somethingElse(String arg);
}
class RealObject implements Interface{
public void doSomething() {
System.out.println("Do something");
}
public void somethingElse(String arg) {
System.out.println("something " + arg);
}
}
class SimpleProxy implements InvocationHandler{
private Object proxied;
/* 需要 java.lang.reflect.Proxy 类
* public static Object newProxyInstance(
* ClassLoader loader,
* Class<?>[] interfaces,
* InvocationHandler h)
* throws IllegalArgumentException
*
* CLassLoader loader:类的加载器
* Class<?> interfaces:得到全部的接口
* InvocationHandler h:得到InvocationHandler接口的子类的实例
*/
public Object newProxyInstance(Object targetObject) {
proxied = targetObject;
return Proxy.newProxyInstance(
targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(),
this);
}
//Object proxy:被代理的对象
//Method method:要调用的方法
//Object[] args:方法调用时所需要参数
//需要 java.lang.reflect.InvocationHandler接口,然后重写 invoke方法
@Override
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
Object res = method.invoke(proxied,args);
Matcher mat = Pattern.compile("(?<=\\.)doSomething(?=\\()").matcher(method.toString());
if(mat.find()) {
System.out.println("Test1");
}
else {
System.out.println("Test2 " + args[0]);
}
return res;
}
}
public class Test{
public static void consumer(Interface iface) {
iface.doSomething();
iface.somethingElse("args");
}
public static void main(String[] args) throws ClassNotFoundException {
consumer(new RealObject());
SimpleProxy simpleProxy = new SimpleProxy();
Interface interface1 = (Interface)simpleProxy.newProxyInstance(new RealObject());
consumer(interface1);
}
}
---输出:
Do something
something args
Do something
Test1
something args
Test2 args
参考资料:
- http://www.cnblogs.com/V1haoge/p/5860749.html
- http://www.cnblogs.com/xiaoluo501395377/p/3383130.html
- http://www.runoob.com/design-pattern/proxy-pattern.html
- https://blog.csdn.net/pangqiandou/article/details/52964066
- https://www.cnblogs.com/baizhanshi/p/6611164.html (强烈推荐!!!)

浙公网安备 33010602011771号