2017-11-03 14 views
0

メソッドを定義し、それを(複数回)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(); 
    } 

..です。

他のコードを実行中...

おかげ

答えて

1

一つの選択肢チェーンに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..."); 
     } 
    } 
} 
+0

私は制約があります。私は複数回サブクラス化できません。私はインターセプタをデコレートするためにデコレータパターンを使用します。ありがとうございました。 – Marpa

+0

私は参照してください。あなたの答えに対する別の解決策で私の回答を更新しました。 – kaos

0

私はインターセプタをデコレートするためにデコレータパターンを使用します。これで、期待通りに動作します。 私のソリューションを共有します:

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(); 
    } 

} 
関連する問題