标签:
1,代理模式:一个类可以用作其他东西的接口,其他类可以通过此类去访问被代理者。package pattern.chp07.proxy;
/**
* 类描述:抽象主题接口
*
* @author: Jing
* @version $Id: Exp$
*
* History: Dec 24, 2014 3:51:12 PM Jing Created.
*
*/
public interface ITV {
/**
*
* 方法说明:购买电视
*
* Author: Jing
* Create Date: Dec 24, 2014 3:51:35 PM
*
* @return void
*/
public void buyTV();
}
package pattern.chp07.proxy;
/**
* 类描述:真实主题角色
*
* @author: Jing
* @version $Id: Exp$
*
* History: Dec 24, 2014 3:53:25 PM Jing Created.
*
*/
public class Buyer implements ITV {
public void buyTV() {
System.out.println("TV");
}
}
package pattern.chp07.proxy;
/**
* 类描述:代理对象
*
* @author: Jing
* @version $Id: Exp$
*
* History: Dec 24, 2014 3:54:04 PM Jing Created.
*
*/
public class BuyerProxy implements ITV{
private Buyer buyer;
public void buyTV() {
System.out.println("Proxy buy ...");
buyer.buyTV();
}
}
package pattern.chp07.proxy.book;
/**
* 类描述:抽象主题
*
* @author: Jing
* @version $Id: Exp$
*
* History: Dec 24, 2014 4:23:56 PM Jing Created.
*
*/
public interface IBorrow {
/**
*
* 方法说明:借阅
*
* Author: Jing
* Create Date: Dec 24, 2014 4:24:18 PM
*
* @return
* @return boolean
*/
boolean borrow();
}
/**
* 类描述:借阅实现类
*
* @author: Jing
* @version $Id: Exp$
*
* History: Dec 25, 2014 9:41:09 AM Jing Created.
*
*/
public class Borrow implements IBorrow {
private Book book;
public Book getBook() {
return book;
}
public void setBook(Book book) {
this.book = book;
}
public boolean borrow() {
//保存数据
//some code
return true;
}
}
package pattern.chp07.proxy.book;
import java.io.RandomAccessFile;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* 类描述:借书代理
*
* @author: Jing
* @version $Id: Exp$
*
* History: Dec 25, 2014 9:43:32 AM Jing Created.
*
*/
public class BorrowProxy implements IBorrow {
private Borrow obj;
private Map<String, Integer> map;
public BorrowProxy(Borrow obj) {
this.obj = obj;
map = new HashMap<String, Integer>();
}
public boolean borrow() {
if (!obj.borrow()) {
return false;
}
Book book = obj.getBook();
Integer i = map.get(book.getNo());
i = (i == null) ? 1 : i + 1;
map.put(book.getNo(), i);
return true;
}
/**
*
* 方法说明:记录日志
*
* Author: Jing Create Date: Dec 25, 2014 10:07:37 AM
*
* @throws Exception
* @return void
*/
public void log() throws Exception {
Set<String> set = map.keySet();
String key = "";
String result = "";
Iterator<String> it = set.iterator();
while (it.hasNext()) {
key = it.next();
result += key + "\t" + map.get(key) + "\r\n";
}
Calendar c = Calendar.getInstance();
RandomAccessFile fa = new RandomAccessFile("c:/log.txt", "rw");
fa.seek(fa.length());
fa.writeBytes(c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-"
+ c.get(Calendar.DAY_OF_MONTH) + "\r\n");
fa.writeBytes(result);
fa.close();
}
}
package pattern.chp07.proxy.book;
/**
* 类描述:书籍实体类
*
* @author: Jing
* @version $Id: Exp$
*
* History: Dec 24, 2014 4:21:57 PM Jing Created.
*
*/
public class Book {
/**
* 书号
*/
private String no;
/**
* 书名
*/
private String name;
public Book(String no, String name) {
super();
this.no = no;
this.name = name;
}
package pattern.chp07.proxy.book;
/**
* 类描述:
*
* @author: Jing
* @version $Id: Exp$
*
* History: Dec 25, 2014 10:20:58 AM Jing Created.
*
*/
public class MainTest {
public static void main(String[] args) throws Exception {
Borrow br = new Borrow();
BorrowProxy proxy = new BorrowProxy(br);
Book book = new Book("1000", "cesf");
br.setBook(book);
proxy.borrow();//借阅
book = new Book("1001", "sdadasd");
br.setBook(book);
proxy.borrow();
proxy.log();
}
}
package pattern.chp07.proxy.emailCount;
/**
* 类描述:抽象主题
*
* @author: Jing
* @version $Id: Exp$
*
* History: Dec 25, 2014 11:01:05 AM Jing Created.
*
*/
public interface IRegister {
/**
*
* 方法说明:等级来信
*
* Author: Jing
* Create Date: Dec 25, 2014 11:01:44 AM
*
* @param msg
* @return void
*/
void regist(String msg);
}
package pattern.chp07.proxy.emailCount;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
* 类描述:创建代理类
*
* @author: Jing
* @version $Id: Exp$
*
* History: Dec 25, 2014 11:09:45 AM Jing Created.
*
*/
public class GenericProxy {
public static Object createProxy(Object obj, InvocationHandler invokeObj) {
Object proxy = Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass()
.getInterfaces(), invokeObj);
return proxy;
}
}
/**
* 类描述:Email信件
*
* @author: Jing
* @version $Id: Exp$
*
* History: Dec 25, 2014 11:05:15 AM Jing Created.
*
*/
public class EmailFrom implements IRegister {
public void regist(String msg) {
System.out.println("From Email");
}
}
package pattern.chp07.proxy.emailCount;
/**
* 类描述:来自传统邮件
*
* @author: Jing
* @version $Id: Exp$
*
* History: Dec 25, 2014 11:06:03 AM Jing Created.
*
*/
public class PostFrom implements IRegister{
public void regist(String msg) {
System.out.println("From Post!");
}
}
/**
* 类描述:计数器动态代理
*
* @author: Jing
* @version $Id: Exp$
*
* History: Dec 25, 2014 11:07:22 AM Jing Created.
*
*/
public class CountInvoke implements InvocationHandler {
private int count = 0;
/**
* 主题对象
*/
private Object obj;
public CountInvoke(Object obj) {
this.obj = obj;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
count++;
method.invoke(obj, args);
return null;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
public class Test {
public static void main(String[] args) {
IRegister email = new EmailFrom();
IRegister post = new PostFrom();
CountInvoke emailInvoke = new CountInvoke(email);
CountInvoke postInvoke = new CountInvoke(post);
IRegister emailproxy = (IRegister) GenericProxy.createProxy(email, emailInvoke);
IRegister postproxy = (IRegister) GenericProxy.createProxy(email, postInvoke);
emailproxy.regist("email");
postproxy.regist("post");
System.out.println(emailInvoke.getCount());
postproxy.regist("post2");
System.out.println(postInvoke.getCount());
}
}
newProxyInstance
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。此方法相当于:
Proxy.getProxyClass(loader, interfaces).
getConstructor(new Class[] { InvocationHandler.class }).
newInstance(new Object[] { handler });
Proxy.newProxyInstance 抛出 IllegalArgumentException,原因与 Proxy.getProxyClass 相同。
参数:
loader - 定义代理类的类加载器
interfaces - 代理类要实现的接口列表
h - 指派方法调用的调用处理程序
返回:
一个带有代理类的指定调用处理程序的代理实例,它由指定的类加载器定义,并实现指定的接口
抛出:
IllegalArgumentException - 如果违反传递到 getProxyClass 的参数上的任何限制
NullPointerException - 如果 interfaces 数组参数或其任何元素为 null,或如果调用处理程序 h 为 null
invoke
Object invoke(Object proxy,
Method method,
Object[] args)
throws Throwable
在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。
参数:
proxy - 在其上调用方法的代理实例
method - 对应于在代理实例上调用的接口方法的 Method 实例。 Method 对象的声明类将是在其中声明方法的接口,该接口可以是代理类赖以继承方法的代理接口的超接口。
args - 包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null。基本类型的参数被包装在适当基本包装器类(如 java.lang.Integer 或 java.lang.Boolean)的实例中。
返回:
从代理实例的方法调用返回的值。如果接口方法的声明返回类型是基本类型,则此方法返回的值一定是相应基本包装对象类的实例;否则,它一定是可分配到声明返回类型的类型。如果此方法返回的值为 null 并且接口方法的返回类型是基本类型,则代理实例上的方法调用将抛出 NullPointerException。否则,如果此方法返回的值与上述接口方法的声明返回类型不兼容,则代理实例上的方法调用将抛出 ClassCastException。
抛出:
Throwable - 从代理实例上的方法调用抛出的异常。该异常的类型必须可以分配到在接口方法的 throws 子句中声明的任一异常类型或未经检查的异常类型 java.lang.RuntimeException 或 java.lang.Error。如果此方法抛出经过检查的异常,该异常不可分配到在接口方法的 throws 子句中声明的任一异常类型,代理实例的方法调用将抛出包含此方法曾抛出的异常的 UndeclaredThrowableException。
/**
* 类描述:动态代理实例
*
* @author: Jing
* @version $Id: Exp$
*
* History: Dec 25, 2014 3:25:08 PM Jing Created.
*
*/
public class ProxyStudy {
@SuppressWarnings("unchecked")
public static void main(String[] args) throws Exception {
Class<?> clazz = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
System.out.println("动态代理产生的类名为: " + clazz.getName());
// 获取动态代理产生的类的构造方法
Constructor<?>[] cons = clazz.getConstructors();
for (Constructor<?> con : cons) {
System.out.println("构造方法: " + con.getName() + "----对应参数: "
+ Arrays.asList(con.getParameterTypes()));
}
// 获取动态类的普通方法
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
System.out.println("方法:" + method.getName() + "----对应参数: "
+ Arrays.asList(method.getParameterTypes()));
}
// 构造方法需要InvocationHandler对象
Constructor<?> constructor = clazz.getConstructor(InvocationHandler.class);
Collection<Object> proxyBuildCollection = (Collection<Object>) constructor
.newInstance(new InvocationHandler() {
ArrayList<Object> target = new ArrayList<Object>();
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("执行方法 : " + method.getName() + "前,参数为:"
+ args.toString());
Object result = method.invoke(target, args);
System.out.println("执行方法 : " + method.getName() + "后。");
return result;
}
});
proxyBuildCollection.add("asd");
proxyBuildCollection.add("asd");
proxyBuildCollection.add("asd");
}
}
读书笔记_java设计模式深入研究 第七章 代理模式 Proxy
标签:
原文地址:http://blog.csdn.net/mergades/article/details/42173893