代理模式:
这个基本上是最简单的代理模式实现了.
对Interface接口方法的调用,都被SimpleProxy截获了.
动态代理:
能够在运行时实现接口但在编译时不用声明其实现接口的特殊类.////
Java的动态代理比代理的思想又向前了一步.因为它可以动态的创建代理并动态地处理对所有代理的方法调用.在动态代理上所做的所有调用都会被重定向到单一的调用处理器上.(Thinking in Java)
SimpleProxy在编译期已经存在,但动态代理可以在运行期生成代理类,及代理实例.
用动态代理改写上面的例子:
此时可以对多个接口进行方法调用的拦截,AOP的实现.
普通代理模式可能要针对一个接口实现一个代理.
动态代理则只需要编写一个调用处理器的实现类,根据传入的代理接口列表动态生成代理类和代理实例.
在这里再给出一个接口,但是对这个接口没有默认实现类.
改写上面的调用处理器实现类:
可能的结果:
methodName:doSomething
proxy:$Proxy0
realSubject.doSomething()...
methodName:somethingElse
proxy:$Proxy0
proxyString
realSubject.somethingElse(proxyString )...
[color=red]methodName:play
proxy:$Proxy0
invoke OtherInterface.play method![/color]
调用处理器截获对OtherInterface.play()方法的调用.作出处理后并返回,因为没有RealSubject,因些也无法向真实对象进行请求转发.
从外部看:好像Interface的实例经过调用处理器的处理,他又实现了另外一个接口.
现再调用处理器的作用不再只是进行对方法截获进行处理,请求转发;
它实际在做一种实现工作,
(只是进行对方法截获进行处理,而没有进行请求转发就可以看成一种重写了)
再从另个一个角度看,此时的调用处理器不只是进行代理,而还有适配器的形,但可能完全没有适配器的目的,因为Interface和OtherInterface完全没有关系.但可以从一个Interface的实例转型为一个OtherInterface.
甚至在调用Proxy.newProxyInstance()方法生成代理实例的时候,不传入RealSubject对象,那么调用处理器完全冲当代理接口的实现类,而没有了请求转发这一步骤.
不过这完全不是代理的初衷了!
注:1处的转发调用是当有传入RealSubject对象时才可以调用,如果传入null,则要进行单独处理.
动态的意思:1.可以横行为一组接口实现横切逻辑.
2.可以在运行时动态实现一个接口实例,Proxy$X为接口的实现类.
public interface Interface {
void doSomething();
void somethingElse(String arg);
}
public class RealSubject implements Interface {
public void doSomething() {
System.out.println("realSubject.doSomething()...");
}
public void somethingElse(String arg) {
System.out.println("realSubject.somethingElse(" + arg + " )...");
}
}
public class SimpleProxy implements Interface {
private Interface real;
public SimpleProxy(Interface obj) {
this.real = obj;
}
public void doSomething() {
System.out.println("simpleProxy--before");
real.doSomething();
}
public void somethingElse(String arg) {
System.out.println("simpleProxy--before");
real.somethingElse(arg);
}
}
public class Main {
public static void main(String[] args) {
Interface obj = new RealSubject();
Interface simpleProxy = new SimpleProxy(obj);
simpleProxy.doSomething();
simpleProxy.somethingElse("testString");
}
}
这个基本上是最简单的代理模式实现了.
对Interface接口方法的调用,都被SimpleProxy截获了.
动态代理:
能够在运行时实现接口但在编译时不用声明其实现接口的特殊类.////
Java的动态代理比代理的思想又向前了一步.因为它可以动态的创建代理并动态地处理对所有代理的方法调用.在动态代理上所做的所有调用都会被重定向到单一的调用处理器上.(Thinking in Java)
SimpleProxy在编译期已经存在,但动态代理可以在运行期生成代理类,及代理实例.
用动态代理改写上面的例子:
public class InvocationHandlerImpl implements InvocationHandler {
private Object target;
public InvocationHandlerImpl(Object obj) {
this.target = obj;
}
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable {
System.out.println("methodName:" + method.getName());
System.out.println("proxy:" + proxy.getClass().getName());
if (args != null) {
for(Object o : args) {
System.out.println(o);
}
}
return method.invoke(target,args); //1:转发请求
}
}
public class Main {
public static void main(String[] args) {
Interface real = new RealSubject();
Interface proxy = (Interface)Proxy.newProxyInstance(Interface.class.getClassLoader(),new Class[]{Interface.class},new InvocationHandlerImpl(real));
proxy.doSomething();
proxy.somethingElse("proxyString");
}
}
此时可以对多个接口进行方法调用的拦截,AOP的实现.
普通代理模式可能要针对一个接口实现一个代理.
动态代理则只需要编写一个调用处理器的实现类,根据传入的代理接口列表动态生成代理类和代理实例.
public interface OtherInterface {
public void play();
}
在这里再给出一个接口,但是对这个接口没有默认实现类.
改写上面的调用处理器实现类:
public class InvocationHandlerImpl2 implements InvocationHandler {
private Object target;
public InvocationHandlerImpl2(Object obj) {
this.target = obj;
}
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable {
System.out.println("methodName:" + method.getName());
System.out.println("proxy:" + proxy.getClass().getName());
if ("play".equals(method.getName())) {
System.out.println("invoke OtherInterface.play method!");
return null;
}
if (args != null) {
for(Object o : args) {
System.out.println(o);
}
}
return method.invoke(target,args);
}
}
public class Main {
public static void main(String[] args) {
Interface real = new RealSubject();
Object proxyObject = Proxy.newProxyInstance(Interface.class.getClassLoader(),new Class[]{Interface.class,OtherInterface.class},new InvocationHandlerImpl2(real));
Interface proxy = (Interface)proxyObject;
proxy.doSomething();
proxy.somethingElse("proxyString");
OtherInterface otherProxy = (OtherInterface)proxyObject;
otherProxy.play();
}
}
可能的结果:
methodName:doSomething
proxy:$Proxy0
realSubject.doSomething()...
methodName:somethingElse
proxy:$Proxy0
proxyString
realSubject.somethingElse(proxyString )...
[color=red]methodName:play
proxy:$Proxy0
invoke OtherInterface.play method![/color]
调用处理器截获对OtherInterface.play()方法的调用.作出处理后并返回,因为没有RealSubject,因些也无法向真实对象进行请求转发.
从外部看:好像Interface的实例经过调用处理器的处理,他又实现了另外一个接口.
现再调用处理器的作用不再只是进行对方法截获进行处理,请求转发;
它实际在做一种实现工作,
(只是进行对方法截获进行处理,而没有进行请求转发就可以看成一种重写了)
再从另个一个角度看,此时的调用处理器不只是进行代理,而还有适配器的形,但可能完全没有适配器的目的,因为Interface和OtherInterface完全没有关系.但可以从一个Interface的实例转型为一个OtherInterface.
甚至在调用Proxy.newProxyInstance()方法生成代理实例的时候,不传入RealSubject对象,那么调用处理器完全冲当代理接口的实现类,而没有了请求转发这一步骤.
不过这完全不是代理的初衷了!
注:1处的转发调用是当有传入RealSubject对象时才可以调用,如果传入null,则要进行单独处理.
动态的意思:1.可以横行为一组接口实现横切逻辑.
2.可以在运行时动态实现一个接口实例,Proxy$X为接口的实现类.