发布于 2016-01-04 01:15:50 | 191 次阅读 | 评论: 0 | 来源: PHPERZ
Java程序设计语言
java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台(即JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称。
代理模式
代理模式是常用的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======
其实我自己现在也是不是很明白准备去看源码,到时候分享给大家,
这个模式主要是搞清楚代理对象和被代理的对象,也就是委托作