java之代理模式

来源:互联网 发布:caffe训练模型 编辑:程序博客网 时间:2024/06/16 06:17

代码来自Java编程思想337页

public interface Iterface {

     abstract void doSomething();
     abstract void someThingElse(String arg);

}

接口提供抽象方法,和方便参数的定义

public class RealObject implements Iterface{


@Override
public void doSomething() {
// TODO Auto-generated method stub
System.out.println("doSomething");
}


@Override
public void someThingElse(String arg) {
// TODO Auto-generated method stub
System.out.println("someThingElse"+arg);
}


}

真实类实现接口,实现接口方法编写具体逻辑


public class SimpleProxy implements Iterface{
    //代理的成员变量用来接收真实对象的引用,在构造器中初始化,真实对象的方法在在理里面执行
private Iterface proxied;
public SimpleProxy(Iterface iterface){
this.proxied=iterface;
}
public void doSomething() {
// TODO Auto-generated method stub
System.out.println("SimpleProxy doSomeThing");
proxied.doSomething();
}


public void someThingElse(String arg) {
// TODO Auto-generated method stub
System.out.println("SimpleProxy someThingElse"+arg);
proxied.someThingElse(arg);
}


}

代理类组合入真实类并且实现接口,这样代理的对象就包含了真实对象和真实对象相同方法名的方法,

真实对象是构造器接收的参数,即要求在创建代理对象时传入一个真实对象的引用,代理类里的方法里面调用

真实类相同方法名的方法,这样代理的一个方法执行时真实类的相应的方法也执行了,类似捆绑在一起的,

可以理解为实体和影子一样。


public class SimpleProxyDemo {
    public static void consumer(Iterface iface){
    iface.doSomething();
    iface.someThingElse("bonobo");
    }
    public static void main(String[] args) {
consumer(new RealObject());//非代理
consumer(new SimpleProxy(new RealObject()));//代理
}
}

用代理模式的好处,目前理解为:代理调用方法时会调用真实类的方法,即你不必知道真实类的

具体代码是如何编辑的。


下面是动态代理:

public class DynaicProxyHandler implements InvocationHandler{
//动态代理的真实对象类型很广
    private Object proxied;

public DynaicProxyHandler(Object proxied){
this.proxied=proxied;
}
//代理对象,真是对象的方法与参数
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
System.out.println("**** proxy:"+proxy.getClass()+
",method:"+method+",args:"+args);
if(args != null){
for(Object arg:args){
System.out.println(""+arg);
}
}
return method.invoke(proxied, args);
}
    
}

就是把上面的简单代理类改了一下,动态代理不是实现我们定义的接口,而是实现Java类库的类

组合进的也不是真实类,而是所有类的基类Object类,从构造器看到,Object的引用在构造器里初始化

,它就是用来接收真实类的对象引用,和简单代理类的初始化一样,只是类型更广泛。Object 

类型的invoke方法叫做方法调用处理器,由于实现的是Java类库的类,具体的过程只能看源码了

下面是个人的浅见,上代码:

public class SimpleDynamicProxy {
    public static void consumer(Iterface iface){
    iface.doSomething();
    iface.someThingElse("bonobo");
    }
    public static void main(String[] args) {
RealObject real =new RealObject();
consumer(real);
Iterface proxy=(Iterface) Proxy.newProxyInstance(
Iterface.class.getClassLoader(),
new Class[]{Iterface.class}, 
new DynaicProxyHandler(real));
consumer(proxy);
}
}

代理对象调用方法时会先执行invoke方法,该方法返回的是method.invoke(proxied, args);

proxied是真实类的对象引用,从程序的输出结果看:

doSomething
someThingElsebonobo
**** proxy:class $Proxy0,method:public abstract void lsw20160104E337.Iterface.doSomething(),args:null
doSomething
**** proxy:class $Proxy0,method:public abstract void lsw20160104E337.Iterface.someThingElse(java.lang.String),args:[Ljava.lang.Object;@723d7c
bonobo
someThingElsebonobo


代理对象每调用一个方法都会执行invoke方法即方法调用处理器,即代理调用方法时会执行完invoke方法

并且返回一个对真实对象方法的调用即method.invoke(proxied, args);这样真实对象就调用了相应的方法

invoke方法有3个参数,真实对象的引用proxied,真实对象调用的方法method,method的参数args,

这样我们可以在invoke方法里加入对这3个参数的操作了。



0 0
原创粉丝点击