动态代理(Dynam......
推荐链接 见证又一个......
动态代理(Dynamic Proxy)
在了解动态代理之前先来简单的回顾下代理模式
一、代理的概念:生活中的代理不胜枚举,譬如你想买一台ipad2(其实我也想买)你肯定不希望跑到美国苹果的总部买回来,多麻烦啊!一般都是希望直接在国内的苹果代理商那里去购买。这样的好处就是节省了不少时间和金钱,当然还避免的很多风险(风险都由代理商帮你完成了)。设计模式中的代理也如同生活中的代理,客户端不直接引用真实对象,而是去引用他的代理对象,由代理对象完成真实对象所要做的一些事情。
二、代理对象所涉及角色:
1. 抽象主题角色:声明抽象主题和代理主题的共同接口,这样可以在使用真实主题角色的地方同时也可以使用代理角色。抽象主题角色一般是接口或者抽象类
2. 真实主题角色:
3. 代理主题角色:通常代理角色包含有真实主题角色的引用,以便操作真实主题对象。因为与真实主题角色有共同的接口,这样可以替代真实主题,通常代理主题不单单处理客户调用传递过来的请求给真实主题,而且会包含一些其他的操作(好比例子中的风险处理就有代理去解决)。
三、代理的类图:
四、代码清单:
RealSubject.java
Java代码
/**
*真实主题对象
*/
public class RealSubject extends Subject {
@Override
public void request() {
System.out.println("realSubject request...");
}
}
/**
*真实主题对象
*/
public class RealSubject extends Subject {
@Override
public void request() {
System.out.println("realSubject request...");
}
}
Subject.java
Java代码
/**
* 抽象主题角色
*
*/
public abstract class Subject {
public abstract void request();
}
/**
* 抽象主题角色
*
*/
public abstract class Subject {
public abstract void request();
}
Proxy.java
Java代码
public class Proxy extends Subject{
private RealSubject realSubject;
public Proxy(RealSubject realSubject) {
this.realSubject = realSubject;
}
private void beforeRequest(){
System.out.println("proxy beforeRequest");
}
@Override
public void request() {
beforeRequest();
realSubject.request();
afterRequest();
}
private void afterRequest(){
System.out.println("proxy afterRequest");
}
}
public class Proxy extends Subject{
private RealSubject realSubject;
public Proxy(RealSubject realSubject) {
this.realSubject = realSubject;
}
private void beforeRequest(){
System.out.println("proxy beforeRequest");
}
@Override
public void request() {
beforeRequest();
realSubject.request();
afterRequest();
}
private void afterRequest(){
System.out.println("proxy afterRequest");
}
}
五、动态代理:
正式进入主题,现在又这样的一个需求,系统中有一百个类真实主题对象,要为其手动的添加代理类可以想象是一个多大的工程。从jdk1.3开始,引入了动态代理,java.lang.reflect.Proxy,JVM可以自己创建代理类,这样不尽提高了效率,而且更灵活。
动态代理三个主要的类:
Proxy,InvocationHandler,Method
Proxy类中主要三个方法:
protected Proxy(InvocationHandler h)
public static Class<?> getProxyClass(ClassLoader loader,
Class<?>... interfaces)
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
1. 分析getProxyClass方法:既然是由JVM创建代理类,首先就必须为其制定ClassLoader,因为所有类都需要类加载器去加载。创建代理的目的是做为客户端和目标对象(真是主题对象)之间的一个中介,所以要为代理类指定一些方法,这里所采用的实现方式就是为其指定一个或者多个接口,JVM生成该代理类时自动的实现这些接口中的方法。这个代理类仅能用作具有相同接口的目标类的代理。
2. InvocationHander:调用处理器,他是一个接口,就申明了一个invoke方法
public Object invoke(Object proxy, Method method, Object[] args)
每一个代理实例都必须指定一个调用处理器,代理对象调用方法时,该方法会指派到调用处理器的invoke()中去。代理的方法封装成invoke中的method对象,其中的参数封装成Object[]
代码清单:
Java代码
public class ProxyTest {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
Collection collection = (Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(), new Class[]{Collection.class}, new InvocationHandler() {
ArrayList list = new ArrayList();
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("方法:"+method.getName()+" 参数:"+Arrays.toString(args));
return method.invoke(list, args);
}
});
collection.add("aaa");
collection.add("aaa");
collection.add("aaa");
collection.add("aaa");
System.out.println(collection.size());
}
}
public class ProxyTest {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
Collection collection = (Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(), new Class[]{Collection.class}, new InvocationHandler() {
ArrayList list = new ArrayList();
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("方法:"+method.getName()+" 参数:"+Arrays.toString(args));
return method.invoke(list, args);
}
});
collection.add("aaa");
collection.add("aaa");
collection.add("aaa");
collection.add("aaa");
System.out.println(collection.size());
}
}
输出结果:
方法:add 参数:[aaa]
方法:add 参数:[aaa]
方法:add 参数:[aaa]
方法:add 参数:[aaa]
方法:size 参数:null
4
六、 AOP原理:http://www.iteye.com/topic/336873
利用动态代理知识可以直接模拟一个aop
Advice.java
Java代码
public interface Advice {
public void before();
public void after();
}
public interface Advice {
public void before();
public void after();
}
MyProxy.java
Java代码
public class MyProxy {
public Object getProxy(final Object target,final Advice advice){
Object object = Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
advice.before();
Object obj = method.invoke(target, args);
advice.after();
return obj;
}
});
return object;
}
}
public class MyProxy {
public Object getProxy(final Object target,final Advice advice){
Object object = Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
advice.before();
Object obj = method.invoke(target, args);
advice.after();
return obj;
}
});
return object;
}
}
大小: 14.5 KB
查看图片附件
|