Java核心技术读书笔记6-5 Java代理

7.代理

7.1 概念
假如你现在有这样两个需求:
1.为某个对象的某个方法做扩展,要求执行方法之前加一些逻辑,执行方法之后加一些逻辑。(例如添加日志)
2.传入的对象与方法不确定,也就是说你需要实现一个通用方法,这个方法能够对传入的任何对象的任何方法做扩展。
显然,对于传入的类型不确定,你需要使用反射来解决以获得他的方法信息。如果你能够通过反射获得要执行的方法对象,那么就可以调用反射的invoke来激活方法。然后,为了扩展方法,可以在invoke之前或之后添加自己希望的逻辑代码完成扩展。这样我们就对传入的对象和指定方法进行了包装,由于这个方法不会立即执行,所以我们需要将包装过后的对象返回。每当这个对象去调用上述原方法时,保证其调用的就是我们包装后的方法即可。这个设计过程就是代理。得到的对象就是代理对象。

7.2 实现
我们可以不去手动编写相应的代码,只需要调用反射包提供好的InvocationHandler类和Proxy类即可。这两个类中的相应方法分别对应我们的扩展相应方法和对原对象做包装的要求。整体实现过程如下:
1.通过接口指定要扩展的方法

public interface MarkMethods {
    void method1();
    int method2(String para);
}

2.使用类扩展这些方法

public class ImplementClass implements MarkMethods{
    @Override
    public void method1() {
        System.out.println("I am method1");
    }

    @Override
    public int method2(String para) {
        System.out.println("I am method2");
        if(para == null){
            return 0;
        }else{
            return para.length();
        }
    }
    public void otherMethod(){
        System.out.println("I am otherMethod");
    }
}

3.实现InvocationHandler,表示如何对方法进行扩展

public class MyInvocation implements InvocationHandler {
    private Object target; //被代理对象
    public MyInvocation(Object target){
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Do something before invoke..."); //扩展功能
        Object res = method.invoke(target, args);
        System.out.println("Do something after invoke..."); //扩展功能
        return res;
    }
}

4.生成代理对象以及测试执行

public class MyProxyTest {
    public static void main(String[] args) {
        MarkMethods target = new ImplementClass(); //被代理的接口类型变量,变量需要引用实现类对象
        InvocationHandler handler = new MyInvocation(target); //指定方法处理器
        MarkMethods proxy = (MarkMethods)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler);//分别指定被代理对象的类加载器、类实现的接口与处理器
        proxy.method1();//代理对象将会调用包装后的方法
        int length = proxy.method2("I am a parameter");
        System.out.println(length);
    }
}

Java核心技术读书笔记6-5 Java代理

上一篇:Python开发之路 - 锁、信号量 、队列


下一篇:Java 设计模式之代理模式