java设计模式-代理模式
- 静态代理
主要有三个角色:抽象角色,代理类,被代理类。
- 抽象角色:封装了代理类和被代理类的共有的特性,通过此接口来实现代理类和被代理类的外观上的一致。
public abstract class Subject {
public abstract void request();
} - 代理类:实现代理的类,当客户端需要访问被代理类时,通过代理类类完成,因此此类中应包含一个被代理类的引用,已实现对被代理类的调用。在完成对被代理对象的调用的同时还可加入自己的操作。
public class ProxySubject extends Subject {
private RealSubject realSubject;
public void request() {
if(null == realSubject){
realSubject = new RealSubject();
}
pre();
realSubject.request();
post();
}
private static void pre(){
System.out.println("before");
}
private static void post(){
System.out.println("after");
}
} - 被代理类:实际实现操作的类,被代理类来调用实现功能。
public class RealSubject extends Subject {
public void request() {
System.out.println("real subject");
}
} - 测试类
public class TestStaticProxy {
public static void main(String[] args) {
Subject subject = new ProxySubject();
subject.request();
}
}
静态代理是在编译期间已经实现了代理类对被代理的代理操作。
- 动态代理抽象角色必须为接口:
public interface Subject {
public void request();
}
动态代理类:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 代理类
* @author Administrator
*
*/
public class DynamicProxy implements InvocationHandler {
//被代理对象的引用
public Object sub;
//在构造方法中初始化被代理对象
public DynamicProxy(Object obj){
this.sub = obj;
}
//第一个参数生成的代理类,第二个参数封装好的方法对象,第三个参数方法的参数
//
//返回值与被调用方法的返回值类型相同
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("before calling method:" + method);
System.out.println(proxy.getClass());
//调用绑定到被代理对象上的相应的方法
Object object = method.invoke(sub, args);
System.out.println("after calling method:" + method);
return object;
}
}
被代理类与静态代理中相同
测试类:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class TestDynamic01 {
public static void main(String[] args) {
//将需要被代理的对象new RealSubject()传递给代理对象,
//则代理对象拥有了被代理对象的引用
InvocationHandler dProxy = new DynamicProxy(new RealSubject());
//使用Proxy类的静态方法newProxyInstance()来生成一个动态的代理类
//当然在生成这个动态代理对象时需要三个参数:
//1.代理对象的类加载器来加载代理类到jvm,可以使用代理类或被代理类的classLoader
//2.被代理类的实现的接口对象class
//3.代理类对象的实例,用来调用方法的一个处理器即调用代理类的invoke方法
//返回一个根据上面参数动态生成的代理对象
Subject sub = (Subject)Proxy.newProxyInstance(RealSubject.class.getClassLoader(),
RealSubject.class.getInterfaces(), dProxy);
//调用动态生成的对象中的方法,根据dProxy对象来运用反射来实现相应方法调用
sub.request();
System.out.println(sub.getClass());
}
}