java设计模式---代理模式

1.代理模式的整体构架

    (1)代理与被代理共同的接口

    (2)代理

    (3)被代理人

     代码举例:

   接口:

 public interface women {
    public void doSomething();
  }
代理类:
public class OnePersonProxy implements women{
	
	private women on;
	public OnePersonProxy(){
		on= new OnePerson();
	}

	public void doSomething() {
        on.doSomething();		
	}

	public women getOn() {
		return on;
	}

	public void setOn(women on) {
		this.on = on;
	}

}
真实类:
public class OnePerson implements women{

	public void doSomething() {
     System.out.println("onePerson do something");		
	}

}
另一个对象调用:
	public static void main(String[] args) {
		
		OnePersonProxy pro= new OnePersonProxy();
		pro.doSomething();

	}

其主要思想是,A与C之间的沟通,通过B进行。代理相当于“中介”,通过代理后,可以有些操作在代理端实现。

动态代理实现:

需要的主要类:

(1) Proxy

      Proxy类提供了用于创建动态代理类和实例对象的方法,它是所创建的动态代理类的父类,它最常用的方法如下:

  • public static Class<?> getProxyClass(ClassLoader loader,Class<?>... interfaces):该方法用于返回一个Class类型的代理类,在参数中需要提供类加载器并需要指定代理的接口数组(与真实主题类的接口列表一致)。
  • public static Object newProxyInstance(ClassLoader loader, Class<?>[]interfaces, InvocationHandler h):该方法用于返回一个动态创建的代理类的实例,方法中第一个参数loader表示代理类的类加载器,第二个参数interfaces表示代理类所实现的接口列表(与真实主题类的接口列表一致),第三个参数h表示所指派的调用处理程序类。

      (2) InvocationHandler接口

      InvocationHandler接口是代理处理程序类的实现接口,该接口作为代理实例的调用处理者的公共父类,每一个代理类的实例都可以提供一个相关的具体调用处理者(InvocationHandler接口的子类)。在该接口中声明了如下方法:

  • public Object invoke(Objectproxy, Method method, Object[] args):该方法用于处理对代理类实例的方法调用并返回相应的结果,当一个代理实例中的业务方法被调用时将自动调用该方法。invoke()方法包含三个参数,其中第一个参数proxy表示代理类的实例,第二个参数method表示需要代理的方法,第三个参数args表示代理方法的参数数组。

动态代理类需要在运行时指定所代理真实主题类的接口,客户端在调用动态代理对象的方法时,调用请求会将请求自动转发给InvocationHandler对象的invoke()方法,由invoke()方法来实现对请求的统一处理。

   package proxy;
	import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Calendar;
import java.util.GregorianCalendar;

	public class DyProxy{
		public static void main(String args[]) {
			InvocationHandler handler = null;
			
			AbstractUserDAO userDAO = new UserDAO();
			<span style="background-color: rgb(255, 0, 0);">handler = new DAOLogHandler(userDAO);</span>
			<span style="color:#FF0000;">AbstractUserDAO proxy = null;</span><span style="background-color: rgb(255, 0, 0);">(定义一个代理)</span>
			//动态创建代理对象,用于代理一个AbstractUserDAO类型的真实主题对象<span style="background-color: rgb(255, 0, 0);">(代理与实体对应上)</span>
			proxy = <span style="background-color: rgb(255, 0, 0);">(AbstractUserDAO)Proxy.newProxyInstance(AbstractUserDAO. class.getClassLoader(), new Class[]{AbstractUserDAO.class}, h</span>andler);
			<span style="color:#FF0000;">proxy.findUserById("张无忌"); //调用代理对象的业务方法</span><span style="background-color: rgb(204, 0, 0);">(代理执行方法,实质是实体方法执行)</span>
			
			System.out.println("------------------------------");
			
			AbstractDocumentDAO docDAO = new DocumentDAO();
			handler = new DAOLogHandler(docDAO);
			AbstractDocumentDAO proxy_new = null;
			//动态创建代理对象,用于代理一个AbstractDocumentDAO类型的真实主题对象
			proxy_new = (AbstractDocumentDAO)Proxy.newProxyInstance(AbstractDocumentDAO.class.getClassLoader(), new Class[]{AbstractDocumentDAO.class}, handler);
			proxy_new.deleteDocumentById("D002"); //调用代理对象的业务方法
		} 
	}
	//抽象UserDAO:抽象主题角色
	interface AbstractUserDAO {
		public Boolean findUserById(String userId);
	}

	//抽象DocumentDAO:抽象主题角色
	interface AbstractDocumentDAO {
		public Boolean deleteDocumentById(String documentId);
	}

	//具体UserDAO类:真实主题角色
	class UserDAO implements AbstractUserDAO {
		public Boolean findUserById(String userId) {
			if (userId.equalsIgnoreCase("张无忌")) {
				System.out.println("查询ID为" + userId + "的用户信息成功!");
				return true;
			}
			else {
				System.out.println("查询ID为" + userId + "的用户信息失败!");
				return false;
			}
		}
	}

	//具体DocumentDAO类:真实主题角色
	class DocumentDAO implements AbstractDocumentDAO {
		public Boolean deleteDocumentById(String documentId) {
			if (documentId.equalsIgnoreCase("D001")) {
				System.out.println("删除ID为" + documentId + "的文档信息成功!");
				return true;
			}
			else {
				System.out.println("删除ID为" + documentId + "的文档信息失败!");
				return false;
			}
		}
	}

	//自定义请求处理程序类<span style="background-color: rgb(204, 0, 0);">(这个类需要通过代理调用,从而执行真实的方法)</span>
	class DAOLogHandler implements InvocationHandler {
		private Calendar calendar;
		private Object object;
		
		public DAOLogHandler() {	
		}
		
	    //自定义有参构造函数,用于注入一个需要提供代理的真实主题对象
		public DAOLogHandler(Object object) {
			this.object = object;
		}
		
		//实现invoke()方法,调用在真实主题类中定义的方法
	    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			beforeInvoke();
	        Object result = method.invoke(object, args); //转发调用
	        afterInvoke();
	        return null;
	    }

	    //记录方法调用时间
	    public void beforeInvoke(){
	    	calendar = new GregorianCalendar();
	    	int hour = calendar.get(Calendar.HOUR_OF_DAY);
	    	int minute = calendar.get(Calendar.MINUTE);
	    	int second = calendar.get(Calendar.SECOND);
	    	String time = hour + ":" + minute + ":" + second;
	    	System.out.println("调用时间:" + time);
	    }

	    public void afterInvoke(){
	    	System.out.println("方法调用结束!" );
	    }
	}
	

主要类:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值