代理模式
代理模式概念:
通常我们不想或者不能直接调用某一类,可以设计出另外一个类来代理我们想调用的类,这种替代其他类执行的模式叫代理模式
代理模式的角色分为三种:真实类 代理类 抽象接口
普通的代理模式实现方法:
原理:实质上是代理类事先有一个真实类的引用,故代理类里面可以调用真实类的方法
//抽象代类或接口
public interface Subject{
public void method();
}
//真实类
public class RealSubject implements Subject{
@Override
public void method() {
// TODO Auto-generated method stub
System.out.println("i am a real subject");
}
}
//代理类
public class MyProxy implements Subject{
private Subject ss;
public MyProxy(){
ss = new RealSubject();
}
@Override
public void method() {
// TODO Auto-generated method stub
beforeMethod();
ss.method();
afterMethod();
}
public void afterMethod(){
System.out.println("after.....");
}
public void beforeMethod(){
System.out.println("before.....");
}
}
但是,这有也缺点:创建代理类里面的真是累引用时,必须真实类存在,而且一个类对应一个代理类,这也是对类的数量一个冲击,况且,如果实现不知道真是累的时候,我们又该如何去代理呢???? 这就引入下面的动态代理模式:
动态代理模式:
动态代理模式和上面差不多类似,不同的是在获取真实类的引用时,我们使用JAVA反射机制动态获取的,而不是直接new,事先创建好
动态代理模式需要用到Proxy和InvocationHandler两个类,前者用用动态获取代理对象,后者用于约束调用者实现
在InvocationHandler,涉及一个重要的方法:
public Object invoke(Object obj, Method method, Object[] para)
第一个是代理类proxy,第二个是我们真实要调用的方法;第三个是方法参数,用于第二个方法参数的
Proxy类产生代理类的方法
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
参数分别是类加载器,通过class文件过去接口,第三个是撒谎那个面的那个handler
实现方法如下:
//代理约束
public class DynamicSubject implements InvocationHandler{
private Object o;
public DynamicSubject(Object o){
this.o = o;
}
@Override
public Object invoke(Object obj, Method method, Object[] para)
throws Throwable {
// TODO Auto-generated method stub
System.out.println("before");
method.invoke(o, para);
System.out.println("after");
return null;
}
}
//单元测试
public class TestDynamicProxy {
@Test
public void test() {
RealSubject rs = new RealSubject();
InvocationHandler ds = new DynamicSubject(rs);
Class cls = rs.getClass();
Subject proxy = (Subject) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), ds);
proxy.println("Dynamic");
}
}