2015-01-11 26 views
6

Supponiamo che io sono un metodo m:Can Byte Buddy può accedere al nome della variabile locale di un metodo?

public void m() { 
    String foo = "foo"; 
    int bar = 0; 
    doSomething(foo, bar); 
} 

voglio usare ByteBuddy allo strumento il codice in modo che al momento della chiamata doSomething in m, metterà automaticamente il valore del foo e bar in un HashMap, praticamente qualcosa si presenta come:

public void m() { 
    String foo = "foo"; 
    int bar = 0; 
    context.put("foo", foo); // new code injected 
    context.put("bar", bar); // new code injected 
    doSomething(foo, bar); 
} 

esiste un modo per fare questo strumentazione via ByteBuddy?

+0

Beh, utilizzando ASM, è certamente possibile, ma questo non è quello che vuoi sentire ... – fge

+0

Puoi per favore inserire la soluzione ASM per questo caso? thx ... Green –

risposta

1

C'è un modo integrato in Byte Buddy per ridefinire il metodo m in questo modo. Byte Buddy espone volontariamente l'API ASM in cima alla quale è implementato il Byte Buddy. ASM offre una documentazione abbastanza ampia che ti mostrerà come farlo. Posso comunque dirti che sarà un bel po 'di codice. Si noti che è necessario compilare qualsiasi metodo con i simboli di debug abilitati, altrimenti queste variabili interne non sono disponibili in fase di esecuzione.

Sei sicuro di volerlo fare? Senza conoscere il tuo caso d'uso esatto, sembra che sia una cattiva idea. Implementando questa soluzione, rendi i nomi delle variabili locali parte della tua applicazione invece di lasciare che siano un dettaglio di implementazione.

Pertanto, suggerisco di utilizzare lo strumento doSomething. Sarebbe questo basti yourn ciò che è fatto facilmente in Byte amici utilizzando un intercettore simile al seguente:

class Interceptor { 
    void intercept(@Origin Method method, @AllArguments Object[] args) { 
    int index = 0; 
    for(Parameter p : method.getParameters()) { 
     context.add(p.getName(), args[index++]); 
    } 
    } 
} 

quest'interceptor potrebbe poi essere utilizzato come segue:

MethodDelegation.to(new Interceptor()).andThen(SuperMethodCall.INSTANCE); 
+0

'doSomething' prenderà qualsiasi argomento arbitrario:' void doSomething (Object ... args) 'Quindi non posso strumentare quel metodo. Lo scenario è quello di implementare un processore del metodo Controller in modo che quando l'utente chiama 'render (foo, bar)', inserisce automaticamente 'foo' e' bar' nella mappa degli argomenti di rendering a cui viene fatto riferimento nel codice di visualizzazione modello di sottolineatura –

+0

In questo caso , dovrai usare ASM e assicurarti di aggiungere i simboli di debug. L'entità più piccola per intercettare Byte Buddy sa che è un metodo e dubito che questo cambierà in futuro. È comunque possibile utilizzare Byte Buddy per fornire un'infrastruttura, ma a parte questo è necessario utilizzare ASM. –