繁体   English   中英

用ByteBuddy装饰方法

[英]Decorate a method with ByteBuddy

如何定义一个方法,然后用ByteBuddy装饰(多次)? 这是我的例子

Builder<Object> builder = new ByteBuddy().subclass(Object.class).name("Dynamic");
    builder = builder.defineMethod("method", void.class, Visibility.PUBLIC)
    .intercept(MethodDelegation.to(new Object(){

        @RuntimeType
        public void intercept(@This Object o) {
            System.out.println("Executing code...");
        }

    }));

    builder = builder.method(ElementMatchers.named("method")).
    intercept(MethodDelegation.to(new Object(){

        @RuntimeType
        public void intercept(@This Object o) {
            System.out.println("Executing other code...");
        }

    }));

    try {
        Class cls = builder.make()
                .load(StructClassBuilder.class.getClassLoader())
                .getLoaded();

        Object obj = cls.newInstance();
        cls.getDeclaredMethod("method").invoke(obj, args);
    } catch (Exception e1) {
        e1.printStackTrace();
    }

输出是

执行其他代码...

我希望输出是

正在执行代码...

执行其他代码...

谢谢

一种选择是使用MethodDelegation.to(...)。addThen(...)方法将拦截器链接起来。

public class ByteBuddyTest {

  public static void main(String[] args) throws Exception {
    DynamicType.Builder<Object> builder = new ByteBuddy().subclass(Object.class).name("Dynamic");
    builder = builder
        .defineMethod("method", void.class, Visibility.PUBLIC)
        .intercept(MethodDelegation.to(Interceptor1.class).andThen(MethodDelegation.to(Interceptor2.class)));

    try {
        Class<?> clazz = builder.make().include().load(ByteBuddyTest.class.getClassLoader()).getLoaded();

        Object obj = clazz.newInstance();
        clazz.getDeclaredMethod("method").invoke(obj, args);
    } catch (Exception e1) {
        e1.printStackTrace();
    }
  }

  public static class Interceptor1 {

      public static void intercept() {
          System.out.println("Executing code...");
      }
  }

  public static class Interceptor2 {

      public static void intercept() {
          System.out.println("Executing other code...");
      }
  }
}

我将使用装饰器模式装饰拦截器,现在它可以按预期工作。 我分享我的解决方案:

private static interface Interceptor{
    public void intercept(@This Object o);
}

private abstract static class InterceptorDecorator implements Interceptor{

    protected Interceptor interceptor;

    public InterceptorDecorator(Interceptor interceptor){
        this.interceptor = interceptor;
    }

    public void intercept(@This Object o) {
        if(interceptor!=null){
            interceptor.intercept(o);       
        }
    }

}

private static class Interceptor1 extends InterceptorDecorator{

    public Interceptor1(Interceptor interceptor) {
        super(interceptor);
    }

    public void intercept(@This Object o) {
        super.intercept(o);
        System.out.println("Executing code...");            
    }

}

private static class Interceptor2 extends InterceptorDecorator{

    public Interceptor2(Interceptor interceptor) {
        super(interceptor);
    }

    public void intercept(@This Object o) {
        super.intercept(o);
        System.out.println("Executing other code...");          
    }

}

public static void main(String[] args) {

    Interceptor interceptor = new Interceptor1(null);
    interceptor = new Interceptor2(interceptor);

    Builder<Object> builder = new ByteBuddy().subclass(Object.class).name("Dynamic");
    builder = builder.defineMethod("method", void.class, Visibility.PUBLIC)
    .intercept(MethodDelegation.to(interceptor));

    try {
        Class cls = builder.make()
                .load(StructClassBuilder.class.getClassLoader())
                .getLoaded();

        Object obj = cls.newInstance();
        cls.getDeclaredMethod("method").invoke(obj, args);
    } catch (Exception e1) {
        e1.printStackTrace();
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM