如何";委托书;Java中的一种方法 首先,我不确定如何最好地说出我的解决方案,所以如果我有时在胡言乱语,那么请考虑一下。

如何";委托书;Java中的一种方法 首先,我不确定如何最好地说出我的解决方案,所以如果我有时在胡言乱语,那么请考虑一下。,java,reflection,Java,Reflection,在库中有一个接口,我希望在不接触物理代码的情况下进行修改 public interface ProxiedPlayer { // .. other code public void setPermission(String permission, boolean state); } 我已经编写了一个第三方库来处理权限,一些开发人员不想采取的步骤可能是,必须挂接到我的API来编辑权限。因此,我问,当调用setPermission时,是否可以让它调用我的调用库中适当的方法来处理权限

在库中有一个接口,我希望在不接触物理代码的情况下进行修改

public interface ProxiedPlayer {
    // .. other code
    public void setPermission(String permission, boolean state);
}
我已经编写了一个第三方库来处理权限,一些开发人员不想采取的步骤可能是,必须挂接到我的API来编辑权限。因此,我问,当调用
setPermission
时,是否可以让它调用我的调用库中适当的方法来处理权限设置,同时忽略预先编程的代码

这是我试图代理的全部内容

我已经研究了Java代理类,但似乎您首先需要尝试代理的对象的实例。考虑到该方法可以在任何时候调用,我不相信这是我的解决方案,但很高兴能够得到纠正

我无法控制实现ProxiedPlayer接口的类的实例化。

编辑:我不知道,我可以订阅几个事件,在那里可以获得玩家的实例,这是尝试代理该方法的合适位置吗?当玩家加入服务器并且可以获得该玩家的实例时,将触发其中一个事件

是否需要为ProxiedPlayer接口的每个实例调用代理代码,或者是否可以简单地以更简单的方式代理方法的每个调用

我的库是一个插件加载后,其他一切是必要的已经完成加载

编辑#2:

import net.md_5.bungee.api.connection.ProxiedPlayer;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class InvocationProxy implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        ProxiedPlayer player = (ProxiedPlayer) proxy;
        if(method.getName().equals("setPermission")) {
            // Call my code here?
        }
        return method.invoke(player, args);
    }
}

如果你不想接触到原始来源,那么我会不会做一些类似于我上面所说的事情,或者我是完全找错了方向,然后,您只能通过使用Java代理来解决此问题,该代理重新定义实现
ProxiedPlayer
接口的任何类,以在调用实际方法之前强制执行安全检查。AspectJ和加载时编织代理已经作为一种可能的解决方案被提到,但您也可以使用my library实现纯Java解决方案:

使用此代理,您或多或少地指定要重新定义属于
ProxiedPlayer
子类型的任何类,以重新定义名为
setPermisson
的(任何)方法,以便调用
MyInterceptor
(这将是您的代码)并随后调用原始实现


请注意,建议的实现假设所有实现
ProxiedPlayer
的类都实现此接口的方法,并且此签名只有一个方法。这可能太简单了,但它显示了方向

在哪里实例化并使用了实现
ProxiedPlayer
的类的实例?它完全在你的图书馆里吗?从你的上一段来看,听起来好像你无法控制这些实现或它们是在什么时候创建的——如果是这样,我认为很难实现你的要求。@Anderschuller我已经更新了我的问题,包括更多的信息,就像我说的,我不知道该怎么说——我的错!类加载器??您可以编写自定义类加载器,该加载器将首先加载实现setPermission的类?这样,您的类的方法将被执行?我不熟悉ClassLoader,因为我从来没有真正使用过它们,但我会研究它!我不控制实现ProxiedPlayer的类的实例化,这有关系吗?不要认为这有关系,类装入器只是在寻找所需资源所在的第一个位置。这意味着,如果具有相同名称和包的类出现在2个JAR中,则将使用第一个找到的类,例如!!谢谢,这绝对符合我的要求,在玩了一段时间后,图书馆看起来绝对令人惊奇!我现在唯一不确定的是我在哪里调用premain方法?你不调用premain方法,JVM会为你这样做。您需要做的就是定义一个代理jar,在启动时添加到Java应用程序中,类似于在类路径中添加一些东西:感谢您迄今为止的帮助,如果有MyInterceptor.class,该方法是否必须是静态的,它是否接受原始参数或ProxiedPlayer的实例+原始参数?我尝试了几个本应记录System.out权限的示例,但无论我如何尝试,都没有发生任何事情。您可以发布一些代码吗?要么在邮件列表上,要么作为一个单独的问题。
public class InterceptionAgent {
  public static void premain(String arguments, 
                             Instrumentation instrumentation) {
    new AgentBuilder.Default()
      .rebase(isSubtypeOf(ProxiedPlayer.class))
      .transform(new AgentBuilder.Transformer() {
        @Override
        public DynamicType.Builder transform(DynamicType.Builder builder) {
          return builder.method(named("setPermission"))
                        .intercept(MethodDelegation.to(MyInterceptor.class)
                      .andThen(SuperMethodInvocation.INSTANCE));
        }
      }).installOn(instrumentation);
  }
}