当前位置: 首页 > 知识库问答 >
问题:

使用ByteBuddy拦截未实现的接口方法

聂琨
2023-03-14

让我们有一个简单的界面:

public interface Person {

    String getFirstName();
    void setFirstName(String firstName);
    
}

现在我这样创建代理:

public class TestClass {

    @Test
    public void testMethod() throws InstantiationException, IllegalAccessException {
        final Class<?> proxy = new ByteBuddy().subclass(Object.class).implement(Person.class)
            // AND INTERCEPTS ALL ABSTRACT AND OBJECT DEFAULT METHODS
            // AND TRAP ALL METHODS EXCEPT CONSTRUCTORS AND FINALIZER
            .method(
                ElementMatchers.isAbstract()
            )
            // AND DELEGATE CALL TO OUR INVOCATION HANDLER STORED IN PRIVATE FIELD OF THE CLASS
            .intercept(MethodDelegation.to(Delegator.class))
            // NOW CREATE THE BYTE-CODE
            .make()
            // AND LOAD IT IN CURRENT CLASSLOADER
            .load(TestClass.class.getClassLoader())
            // RETURN
            .getLoaded();

        final Person theInstance = (Person) proxy.newInstance();
        theInstance.setFirstName("ABC");
        theInstance.getFirstName();
    }

    public static class Delegator {

        @RuntimeType
        public static Object intercept(@This Object proxy, @Origin Method method, @AllArguments Object[] args) throws Throwable {
            System.out.println("Intercept A: " + proxy + ", " + method + ", " + args);
            return null;
        }

        @RuntimeType
        public static Object intercept(@This Object proxy, @Origin Method method) throws Throwable {
            System.out.println("Intercept B: " + proxy + ", " + method);
            return null;
        }

        @RuntimeType
        public static Object interceptE(@This Object proxy, @DefaultMethod(nullIfImpossible = true) Method defaultMethod, @SuperMethod(nullIfImpossible = true) Method superMethod) throws Throwable {
            System.out.println("Intercept C: " + proxy + ", " + defaultMethod + ", " + superMethod);
            return null;
        }

        @RuntimeType
        public static Object interceptE(@This Object proxy, @DefaultMethod(nullIfImpossible = true) Method defaultMethod, @SuperMethod(nullIfImpossible = true) Method superMethod, @AllArguments Object[] args) throws Throwable {
            System.out.println("Intercept D: " + proxy + ", " + defaultMethod + ", " + superMethod + ", " + args);
            return null;
        }

    }

}

当我执行测试时,我看到以下输出:

Intercept C: net.bytebuddy.renamed.java.lang.Object$ByteBuddy$MVjuc1JA@147ed70f, null, null
Intercept C: net.bytebuddy.renamed.java.lang.Object$ByteBuddy$MVjuc1JA@147ed70f, null, null

似乎我永远无法访问被调用方法的方法签名,如果它起源于接口,并且不是由超类实现的?!

当我调用实例时,我也会这样想。setFirstName(“ABC”)我会看到截取D:,它也接受所有输入参数。

我错过了什么?我看了留档,但我仍然很困惑。

一般来说,我想创建Delegator,它捕获代理类中的所有方法,并处理以下情况:

  • 执行一些操作,然后将调用传播到原始方法
  • 做某事并返回它自己的结果,而不调用原始mehod

为此,我需要访问:

  • 代理实例
  • 调用方法
  • 参数
  • 如何调用原始方法体的方法(如果它不是抽象的)

我如何做到这一点?

共有1个答案

伯英武
2023-03-14

Auch——问题在于,在不同的包中,某些注释在ByteBuddy中声明了两次——例如:

net.bytebuddy.implementation.bind.annotation.AllArguments
net.bytebuddy.asm.Advice.AllArguments

当使用实现包中的注释时,一切正常。真是个讨厌的陷阱!

 类似资料:
  • 让我有一个这样的界面: 还有这样一个实现类: 现在我想使用bytebuddy创建一个拦截器/代理,它捕捉对setter的调用,存储更改后的值,并调用real方法。 最后,我想向拦截器/代理“询问”被调用的setter和更改的值。 我尝试了很多考虑也教程,但到目前为止,我发现没有工作的解决方案。也许有人可以帮助我。 这是拦截器: 以下是我当前的“测试”代码: 编辑:

  • 我一直在使用字节好友来监控应用程序的行为,我想在执行特定方法之前检查其中一个应用程序类的数组字段是否已更新。我已经阅读了字节好友留档和堆栈溢出问题,并找到了一些有用的留档,了解如何使用拦截字段访问。 然而,因为我感兴趣的领域是一个数组,中的和事件似乎无关紧要。 是否可以使用ByteBuddy跟踪数组字段的更新?

  • 本文向大家介绍SpringBoot拦截器实现登录拦截的方法示例,包括了SpringBoot拦截器实现登录拦截的方法示例的使用技巧和注意事项,需要的朋友参考一下 源码 GitHub:https://github.com/291685399/springboot-learning/tree/master/springboot-interceptor01 SpringBoot拦截器可以做什么 可以对UR

  • 本文向大家介绍Struts拦截器实现拦截未登陆用户实例解析,包括了Struts拦截器实现拦截未登陆用户实例解析的使用技巧和注意事项,需要的朋友参考一下 本文研究的主要是Struts拦截器实现拦截未登陆用户,具体实现如下。 首先建立一个工具类: checkPrivilegeInterceptor:这个类继承interceptor,这是一个接口,要实现三个方法,要是觉得比较多的话,可以继承他的实现类A

  • 问题内容: 我正在使用Java EE 6和Jboss AS7.1,并尝试使用拦截器绑定(来自jboss网站的示例)。 我有一个InterceptorBinding注解: 拦截器: 还有一个豆: 但是拦截器没有被称为。。。 在编写此代码时将调用拦截器: 谢谢你的帮助。 问题答案: 您是否按照参考示例中的说明启用了拦截器? 缺省情况下,bean档案没有通过拦截器绑定绑定的已启用拦截器。必须通过将侦听器

  • 本文向大家介绍Android来电拦截的实现方法,包括了Android来电拦截的实现方法的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Android来电拦截的方法,供大家参考,具体内容如下 权限 拨号广播—PhoneStateReceiver 来电挂断 BlockCallHelper 看主界面MainActivity 最后看AIdl层面 ITelephony.aidl Neighbo