代理模式
代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发 给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而 是通过调用委托类的对象的相关方法,来提供特定的服务。
按照代理的创建时期,代理类可以分为两种。
静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
动态代理:在程序运行时,运用反射机制动态创建而成。
代理模式可以举一个很简单的例子,就是房屋中介,当然我没去过,为了写这个模式,我就去看了一下,买不起房的人你懂得
这里有两个对象,一个是代理对象,一个是被代理对象,代理对象就是房屋中介
今天A君要买房,他看中了一个房子,但是需要很多手续,他本人上市公司老总,没有那么多时间跑,你知道中国就是喜欢难为你,就是喜欢办证,让你跑,A君老总来的,没时间,也不乐意跑,他找到B中介公司,和他们说我看中了那个房子,需要你们代理一下,帮我把三证拿到,我给你佣金,这就是典型的代理,中介不买房,只帮顾客做一下跑腿的事情,真正发出这个买房的动作的是被代理者
现在让我们开始最简单的静态代理模式
代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口这句话很明显,就是告诉我们,代理和被代理的关系
代理对象和被代理对象都需要实现的接口Count
package org.heinrich.proxy; /** * 定义了一个账户 * * @author heinrich * */ public interface Count { // 查询账户 public void queryCount(); // 修改账户 public void updateCount(); }
然后就是被代理对象CountImpl
package org.heinrich.proxy; public class CountImpl implements Count { @Override public void queryCount() { System.out.println("我正在查询账户"); } @Override public void updateCount() { System.out.println("我正在修改账户"); } }
那么现在我们重点来了,就是这个代理对象
package org.heinrich.proxy; /** * 账户的代理类,代理账户的查询还有修改方法 * @author heinrich * */ public class CountProxy implements Count{ private CountImpl countImpl; public CountProxy(CountImpl countImpl) { this.countImpl = countImpl; } public void queryCount(){ System.out.println("查询前-----"); countImpl.queryCount(); System.out.println("查询后-----"); } public void updateCount() { System.out.println("修改前----"); countImpl.updateCount(); System.out.println("修改后----"); } public CountImpl getCountImpl() { return countImpl; } public void setCountImpl(CountImpl countImpl) { this.countImpl = countImpl; } }
现在见证奇迹的时候到了
package org.heinrich.proxy; public class CountTest { public static void main(String[] args) { //被代理都像 CountImpl countImpl = new CountImpl(); //代理对象 CountProxy countProxy = new CountProxy(countImpl); //代理方法 countProxy.queryCount(); countProxy.updateCount(); } } 查询前----- 我正在查询账户 查询后----- 修改前---- 我正在修改账户 修改后----
静态代理通过观察我们发现,他每次只能代理一个对象,如果在架构的时候你用这个方式,你发现你的代码会出现很多代理对象
能不能有一个代理对象又能买房又能给你租房,还能给你叫车
当然有那就是动态代理
动态代理的特点
首先让我们来了解一下如何使用 Java 动态代理。具体有如下四步骤:
通过实现 InvocationHandler 接口创建自己的调用处理器;
通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;
通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;
通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。
public interface InvocationHandler {
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;
}
参数说明:
Object proxy:指被代理的对象。
Method method:要调用的方法
Object[] args:方法调用时所需要的参数
可以将InvocationHandler接口的子类想象成一个代理的最终操作类,替换掉ProxySubject。
Proxy类:
Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类,此类提供了如下的操作方法:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
参数说明:
ClassLoader loader:类加载器
Class<?>[] interfaces:得到全部的接口
InvocationHandler h:得到InvocationHandler接口的子类实例
上代码
新建一个什么都可以做的万能代理对象
CountInvocationHandler
package org.heinrich.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** *实现一个动态的代理对象 */ public class CountInvocationHandler implements InvocationHandler { //目标对象,也就是买房的人,就是买房的那个人的实现 private Object target; //通过构造器把买房的传入 public CountInvocationHandler(Object target) { super(); this.target = target; } /** * 目标对象调用的方法,也就是房屋中介需要代理的东西 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("======before======"); Object result = method.invoke(target, args); System.out.println("======after======"); return result; } /** *获取目标对象的代理方法 ,返回一个代理对象,也就是返回买房的人的接口 */ public Object getProxy(){ return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } } /** *用于测试的方法 */ package org.heinrich.proxy; public class DynamicProxyTest { public static void main(String[] args) { CountImpl count = new CountImpl();创建一个买房的对象 CountInvocationHandler handler = new CountInvocationHandler(count);//找到房屋中介 Count proxy = (Count)handler.getProxy();房屋中介帮你代理 proxy.updateCount();//你只要做你自己买房的动作 } } ======before====== 我正在修改账户 ======after====== 其实我自己现在也是不是很明白准备去看源码,到时候分享给大家, 这个模式主要是搞清楚代理对象和被代理的对象,也就是委托作