`

设计模式之代理模式(静态代理和动态代理)

阅读更多
    最近在看spring的aop方面的知识,aop是基于动态代理模式实现的。所以顺便看了关于代理模式方面的知识点,现在把这些记录下来。
    代理模式有两种实现:静态代理和动态代理。
    代理模式涉及三个概念:委托(者)、代理(者)和主题接口。
     听一个故事,找着与代理模式涉及的三个概念相对应的内容。
     秀才作为一个委托者,委托(代理)媒婆去告诉姑娘自己的想法(比如要身材好、性感、知性、善良等),而媒婆必须要遵照秀才的约定的规则(接口)去告诉姑娘秀才的意愿。最终二者建立起感情,但是这个过程中两个人并没有参与进来,而是通过媒婆作为代理来传递信息。

  一、静态代理
     静态代理要求:代理类和被代理类都必须实现同一个接口,在代理类中实现事务操作等横切业务逻辑,被代理类中只保留核心业务逻辑。
     缺点:当方法很多时,势必要为每个方法都要进行代理操作,导致增加了代码的复杂度,所以静态代理不能胜任方法较多的情况。
     比如要在输出“HelloWorld”前打印一个字符串“Welcome”
A:先定义一个接口类
package proxy;
public interface HelloWorld {
    public void print();
//  public void say();
}


B: 定义一个该接口的实现类
package proxy;   
public class HelloWorldImpl implements HelloWorld{
    public void print(){
        System.out.println("HelloWorld");    
    }    
//  public void say(){    
//      System.out.println("Say Hello!");    
//  }    
} 
 

C:定义一个静态代理类
package proxy; 
public class StaticProxy implements HelloWorld{    
    public HelloWorld helloWorld ;    
    public StaticProxy(HelloWorld helloWorld){    
        this.helloWorld = helloWorld;    
    }    
    public void print(){ 
        System.out.println("Welcome");    
        //相当于回调    
        helloWorld.print();    
    }        
//  public void say(){    
//      //相当于回调    
//      helloWorld.say();    
//  }    
}    


D: 一个测试类:
package proxy;   
public class TestStaticProxy {    
   public static void main(String[] args){    
        HelloWorld helloWorld = new HelloWorldImpl();    
        StaticProxy staticProxy = new StaticProxy(helloWorld);    
        staticProxy.print();  
//      staticProxy.say();    
    }    
}


二、动态代理
    在java中要实现动态代理机制,则需要java.lang.reflect.InvocationHandler接口和java.lang.reflect.Proxy类的支持。
    public interface InvocationHandler{
          public  Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}

参数:
proxy - 在其上调用方法的代理实例
method - 对应于在代理实例上调用的接口方法的 Method 实例。Method 对象的声明类将是在其中声明方法的接口,该接口可以是代理类赖以继承方法的代理接口的超接口。
args - 包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null。基本类型的参数被包装在适当基本包装器类(如 java.lang.Integer 或 java.lang.Boolean)的实例中。

   Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类。
 
import java.lang.reflect.InvocationHandler ;
import java.lang.reflect.Proxy ;
import java.lang.reflect.Method ;
interface Subject{
	public String say(String name,int age) ;	// 定义抽象方法say
}
class RealSubject implements Subject{	// 实现接口
	public String say(String name,int age){
		return "姓名:" + name + ",年龄:" + age ;
	}
};
class MyInvocationHandler implements InvocationHandler{
	private Object obj ;
	public Object bind(Object obj){
		this.obj = obj ;	// 真实主题类
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this) ;
	}
	public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
		Object temp = method.invoke(this.obj,args) ;	// 调用方法
		return temp ;
	}
};
public class DynaProxyDemo{
	public static void main(String args[]){
		Subject sub = (Subject)new MyInvocationHandler().bind(new RealSubject()) ;
		String info = sub.say("曾召帅",23) ;
		System.out.println(info) ;
	}
};

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics