今天在类里面,我们正在讨论Java编程中的反射(reflection)。今天的类(class)的一部分是关于在Java中使用 InvocationHandler ,而不仅仅是实现接口(interface)。
当我问老师使用调用处理程序有什么好处时,没有一个明确的答案。
假设我们有一个界面插件

public interface Plugin {
    void calculate(double a, double b);
    String getCommand();
}

您可以在类中轻松实现此接口(interface)乘以
public class Multiply implements Plugin {
    @Override
    public void calculate(double a, double b){
         return a * b;
    }

    @Override
    public String getCommand(){
         return "*";
    }
}

那为什么我还要使用 InvocationHandler 的另一个实现?
 public class MyMock {
     public static Object createMock(Class myClass) {
         InvocationHandler handler = new MyInvocationHandler();
         Object result = Proxy.newProxyInstance(myClass.getClassLoader(), new Class[]{myClass}, handler);
         return result;
     }
 }

提前致谢 :)

最佳答案

Proxy是动态proxy,它使您可以在运行时更改时对象的行为,而不必在编译时选择来决定它的行为。

例如,假设我们只想在晚上返回空值。如果要静态地实现它,则需要使用类似以下内容的方法将逻辑写入所有类中

if(isNight())
    return null;
return normalValue;

这要求您实际上可以更改类,并且需要将所有都更改为类。

但是,使用Proxy,您可以将上述逻辑写入InvocationHandler,普通类甚至都不知道它们的值在夜间没有使用。您的代码现在使用的是动态代理,而不是原始的类,但是它不知道它们之间的区别。

这还允许您具有多个InvocationHandlers,因此您可以使用参数运行代码以决定是否要记录调用,出于安全原因而阻止调用或任何其他此类事情,而这对于静态实现是非常不可能的。

但是,您不太可能直接使用这些类,因为它们的级别很低。但是,AOP使用动态代理或字节码操作来完成其任务。如果您曾经使用过Spring,则很可能在不知道的情况下使用了InvocationHandler。将@Transactional放在方法上时,InvocationHandler会拦截方法调用并为您启动(和结束)事务。

10-04 14:41