代理模式:
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 )...
methodName:play
proxy:$Proxy0
invoke OtherInterface.play method!
调用处理器截获对OtherInterface.play()方法的调用.作出处理后并返回,因为没有RealSubject,因些也无法向真实对象进行请求转发.
从外部看:好像Interface的实例经过调用处理器的处理,他又实现了另外一个接口.
现再调用处理器的作用不再只是进行对方法截获进行处理,请求转发;
它实际在做一种实现工作,
(只是进行对方法截获进行处理,而没有进行请求转发就可以看成一种重写了)
再从另个一个角度看,此时的调用处理器不只是进行代理,而还有适配器的形,但可能完全没有适配器的目的,因为Interface和OtherInterface完全没有关系.但可以从一个Interface的实例转型为一个OtherInterface.
甚至在调用Proxy.newProxyInstance()方法生成代理实例的时候,不传入RealSubject对象,那么调用处理器完全冲当代理接口的实现类,而没有了请求转发这一步骤.
不过这完全不是代理的初衷了!
注:1处的转发调用是当有传入RealSubject对象时才可以调用,如果传入null,则要进行单独处理.
动态的意思:1.可以横行为一组接口实现横切逻辑.
2.可以在运行时动态实现一个接口实例,Proxy$X为接口的实现类.
分享到:
相关推荐
- 静态代理与动态代理 - 常见的动态代理实现 - JDK Proxy - CGLIB - JDK Proxy 和 CGLIB 的对比 - 动态代理的实际应用 - Spring AOP 说在前面:今天我们来聊一聊 Java 中的代理,先来聊聊故事背景: 小明想...
本资源包含了博主博客中的代码,用一个黄牛买票的例子帮助新手理解静态代理与动态代理的原理
这里提供了静态代理和动态代理的入门写法~一看即懂!
代理模式 代理模式是常用的Java ...代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
一个静态代理和动态代理的小例子,开发时使用的工具是myeclipse,直接使用myeclipse工具导入即可,希望能 给大家理解这方面的入门知识带来些作用,同时也希望大家指出不足,我可以更加进行改进
2: 动态代理demo 举例实际应用场景(载入数据库驱动的时候,使用AIDL与系统Servic进行通信) 3: 动态代理使用到基础理论:ClassLoader 加载.class字节码文件得到 , Class对象, Class对象通过 newProxyInstance ...
JDK动态代理,关于jdk动态代理的问题!详细的说明!JDK动态代理JDK动态代理
JAVA静态代理和动态代理
java静态代理 jdk动态代理 cglib动态代理 代理原理
基于java的jdk动态代理, 比较了静态代理与动态代理的区别,以及动态代理的底层实现,反编译class文件 jdk动态代理和cglib的区别
结合spring框架实现的动态代理代理,spring,Proxy
动态代理及其生成的代理类,可以反编译查看其类的结构。
Java静态代理和动态代理
Java设计模式——代理设计模式(静态代理和动态代理) 各种情况例子源码
对代理模式与Java动态代理类的理解说明
动态代理动态代理动态代理动态代理动态代理动态代理动态代理动态代理动态代理动态代理动态代理动态代理动态代理动态代理
java代理机制 JDK动态代理和cglib代理 详解
资源列举了设计模式中的静态代理和动态代理的简单java实现,jdk1.8版本经过测试验证,对于想学习设计模式的童靴应该有所帮助
附件为java 动态代理实例,有全码,包括测试代码。 代码少,注释全。 对理解代理非常不错。
jdk 的动态代理和CGLIB代理