我正在尝试一些可以拦截类中方法的方法拦截器。我尝试使用cglib,bytebuddy。我不能使用普通的Java代理类,因为它是一个类。有没有办法拦截我的final
方法。
这是我尝试过的。
//我的目标类,
public class Hello {
public final String sayHello(){
//return lower case hello
return "hello";
}
}
//主要应用程序
public class InterApp {
public static void main(String[] d) throws Exception {
new InterApp().loadclassDD();
}
public void loadclassDD() throws Exception {
//Byte-buddy
Hello helloObject1 = new ByteBuddy()
.subclass(Hello.class)
.method(named("sayHello"))
.intercept(MethodDelegation.to(LoggerInterceptor.class))
.make()
.load(getClass().getClassLoader(),
ClassLoadingStrategy.Default.WRAPPER).getLoaded()
.newInstance();
System.out.println(helloObject1.sayHello());
//CGLIB
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Hello.class);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2,
MethodProxy arg3) throws Throwable {
System.out.println("method name " + arg1.getName());
return arg3.invokeSuper(arg0, arg2).toString().toUpperCase();
}
});
Hello proxy = (Hello) enhancer.create();
System.out.println(proxy.sayHello());
}
}
// LoggerInterceptor - Byte-buddy实现
public class LoggerInterceptor {
public static String log(@SuperCall Callable<String> zuper)throws Exception {
System.out.println("Method intercepted");
return zuper.call().toUpperCase();
}
}
如果我从方法中移除最终量词,则两者都在工作(提供大写HELLO
作为输出)。这是什么原因。?有没有办法实现这个目标?如果我的理解是错误的,请纠正我。
答案 0 :(得分:0)
您可以引入一个由最终课程实现的界面。这样,代理方法将成为一种选择,因为代理可以委托给原始类,同时仍然保持实现的最后一个方面。
Byteman会失败,因为您正在尝试子类化并覆盖最终方法。如果你手动编码或通过一些字节码操作lib,这没关系。它只是违反了你的班级定义的合同。因此即使它起作用,它可能仍然是一个坏主意,因为原始类的作者定义了最终方面是有原因的。
答案 1 :(得分:0)
与上述答案似乎暗示/可能使用Byteman更改方法sayHello的定义相反,即使它是最终的。例如,以下Byteman规则:
RULE更改返回值 CLASS你好 方法说你好 出口 如果是真的 DO $! = $! +&#34;来自Byteman&#34; ENDRULE
将更新返回的字符串为&#34; Hello来自Byteman&#34;。