私はの目的と使用方法を理解しようとしていますAdvice.withCustomMapping().bind(...)
、それは私のユースケースを助けることができるかどうかを確認するために、。
Javadocを読みますAdvice.withCustomMapping()
:
その後、動的に計算、一定の値にバインドされたカスタム注釈の設定が可能になります。
ここで私はこのパターンを適用しようとしていたユースケースは、次のとおりです。
public @interface Name {
}
public abstract class AgentRule {
private final String className = getClass().getName();
public final Advice.WithCustomMapping advice() {
return Advice.withCustomMapping().bind(Name.class, className);
}
public static boolean isEnabled(final String className, final String origin) {
...
}
public abstract Iterable<? extends AgentBuilder> buildAgent(AgentBuilder builder) throws Exception;
}
public class ServletContextAgentRule extends AgentRule {
public static boolean filterAdded = false;
@Override
public Iterable<? extends AgentBuilder> buildAgent(final AgentBuilder builder) throws Exception {
return Arrays.asList(builder
.type(named("org.eclipse.jetty.servlet.ServletContextHandler"))
.transform(new Transformer() {
@Override
public Builder<?> transform(final Builder<?> builder, final TypeDescription typeDescription, final ClassLoader classLoader, final JavaModule module) {
return builder.visit(advice().to(JettyAdvice.class).on(isConstructor()));
}})
.type(not(isInterface()).and(hasSuperType(named("javax.servlet.ServletContext"))
// Jetty is handled separately due to the (otherwise) need for tracking state of the ServletContext
.transform(new Transformer() {
@Override
public Builder<?> transform(final Builder<?> builder, final TypeDescription typeDescription, final ClassLoader classLoader, final JavaModule module) {
return builder.visit(advice().to(ServletContextAdvice.class).on(isConstructor()));
}}));
}
public static class JettyAdvice {
@Advice.OnMethodExit
public static void exit(final @Name String className, final @Advice.Origin String origin, final @Advice.This Object thiz) {
if (isEnabled(className, origin))
filterAdded = JettyAgentIntercept.addFilter(thiz);
}
}
public static class ServletContextAdvice {
@Advice.OnMethodExit
public static void exit(final @Name String className, final @Advice.Origin String origin, final @Advice.This Object thiz) {
if (isEnabled(className, origin))
filterAdded = ServletContextAgentIntercept.addFilter(thiz);
}
}
}
事実上、私がやろうとしていることから、リレー情報であるインスタンスのコンテキストのServletContextAgentRule
に静的コンテキストのJettyAdvice
とServletContextAdvice
。アドバイスメソッドは静的なことになっているので、私は効果的クラスを含む外部リレーメカニズムのいくつかの種類を構築することなく、(これらのメソッドにインスタンスの状態を取得する方法を把握することはできません。< - >のインスタンスは、すべてのサブクラスでコピー+貼り付けたコードが得られ、マップさAgentRule
)。このユースケースは、関係プロジェクトに適用されているルールの多くを、私が最もパフォーマンスとこれを行うには、最も簡潔な方法を把握しようとしている理由です。
私はこのアプローチをしようとするとAdvice.withCustomMapping().bind(...)
、私は言ってByteBuddyから例外を取得します:
java.lang.IllegalStateException: org.eclipse.jetty.servlet.ServletContextHandler() does not define an index 0
目的であるAdvice.withCustomMapping().bind(...)
メソッドシグネチャに存在する特定の引数を上書きするだけでは?私は、javadocをこのの言及を見つけることができなかった、とオンラインの他の例を見て、私は私のユースケースが働くべきであると考えているようです。
あなたの必要性
@Retention(RUNTIME)
public @interface Name { }
それ以外の場合はバイトバディは、あなたの注釈を参照し、同じインデックスを持つ引数でデフォルトにフォールバックすることはできません。