设计模式学习笔记:一、代理模式(动态代理步骤+举例)

代理模式实现步骤:
       1.声明接口:注册需要被监听行为名称
       2.接口实现类: 扮演被监控的类,负责被监听方法实现细节
       3.InvocationHanler接口实现类:
                                    1.次要业务/增强业务
                                    2.将次要业务与被监听方法绑定执行
       4.代理监控对象:
                        被监控类内存地址,被监控类实现的接口,
                        InvocationHandler实现类的实例对象
 

举例:

饭前便后要洗手

这里:主要业务是吃饭和上厕所,次要业务是洗手

1.声明接口,声明主要业务是吃饭和上厕所

public interface BaseService {
     public void eat();
     public void wc();
}

2.接口实现类,要实现吃饭和上厕所的实现类,这里拿person和dog做区分

public class Dog implements BaseService {

	@Override
	public void eat() {
	   System.out.println("啃骨头");
	}

	@Override
	public void wc() {
		 System.out.println("三腿立");

	}

}
public class Person implements BaseService {

	@Override
	public void eat() {//主要业务,代理模式要求开发人员只关心主要业务
	
        System.out.println("使用筷子吃饭....");
	}

	@Override
	public void wc() {
		   System.out.println("测试地球重力是否存在");

	}

}

3.次要业务要实现InvocationHanler类,并重写invoke方法

public class Invaction implements InvocationHandler {

	    private BaseService    obj;//具体被监控对象
	    
	    public Invaction(BaseService param){
	    	this.obj =param;
	    }
	
	/*
	 * 
	 *  invoke方法:在被监控行为将要执行时,会被JVM拦截
	 *             被监控行为和行为实现方会被作为参数输送invoke
	 *             ****通知JVM,这个被拦截方法是如何与当前次要业务方法绑定实现 
	 *  invoke方法三个参数
	 *  
	 *           int v= 小明.eat();//JVM拦截
	 *            eat方法封装为Mehtod类型对象
	 *            eat方法运行时接受所有的实参封装到Object[]
	 *            将负责监控小明的代理对象作为invoke方法第一个参数
	 * 
	 */
	@Override
	public Object invoke(Object porxy, Method method, Object[] params) throws Throwable {
		     //0.局部变量,接受主要业务方法执行完毕后返回值
		     Object value;
		    //1.确认当前被拦截行为
		    String methodName= method.getName();
		    //2.根据被拦截行为不同,决定主要业务和次要业务如何绑定执行
		    if("eat".equals(methodName)){//饭前要洗手
		    	wash();                            //洗手
		    	value=method.invoke(this.obj, params);   //吃饭
		    }else{//便后要洗手
		    	value=method.invoke(this.obj, params);
		    	wash();
		    }
		return value; //返回被拦截方法,需要调用地方
	}
	
	//次要业务
	public void wash(){
		System.out.println("-----祈祷----");
	}

}

4.创建代理监控对象:

public class ProxyFactory {
	/*
	 * 
	 *  JDK动态代理模式下,代理对象的数据类型
	 *  应该由监控行为来描述 
	 *  参数: Class文件,监控类
	 */
	public static  BaseService Builder(Class classFile)throws Exception {
		
		//1.创建被监控实例对象
		 BaseService obj=  (BaseService) classFile.newInstance();
		//2.创建一个通知对象
		 InvocationHandler adviser= new Invaction(obj);
		 //3.向JVM申请负责监控obj对象指定行为的监控对象(代理对象)
		 /*
		  *  loader:被监控对象隶属的类文件在内存中真实地址
		  *  interfaces:被监控对象隶属的类文件实现接口
		  *  h:监控对象发现小明要执行被监控行为,应该有哪一个通知对象进行辅助
		  */
		 BaseService $proxy= (BaseService) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), adviser);
	     return $proxy;
	}

}

测试:

public static void main(String[] args) throws Exception {
	   
		//mike.eat();
		//Person mike = new Person();
        BaseService dog= ProxyFactory.Builder(Dog.class);
        dog.eat();//专门负责监控mike的代理对象
        
        BaseService mike= ProxyFactory.Builder(Person.class);
        mike.eat();
       
}

原文地址:https://www.cnblogs.com/dulinan/p/12033034.html