gpt4 book ai didi

java - CGLIB 无法拦截父类(super class)/超接口(interface)中的方法

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:36:12 25 4
gpt4 key购买 nike

可能是我想得不够认真,或者答案真的难以捉摸。快速场景(尝试代码。编译)。

考虑一个遗留接口(interface)

public interface LegacyInterfaceNoCodeAvailable{
void logInfo(String message);
}

考虑上述接口(interface)的遗留实现

public abstract class LegacyClassNoCodeAvailable implements LegacyInterfaceNoCodeAvailable{

public abstract void executeSomething();

public void rockItOldSchool(){
logInfo("bustin' chops, old-school style");
}

@Override
public void logInfo(String message){
System.out.println(message);
}
}

现在我作为一个雄心勃勃的人进来,并为"new"系统编写了一个类,但它在“旧”框架内运行,因此我必须扩展遗留基类。

public class lass SpankingShiny extends LegacyClassNoCodeAvailable{

public void executeSomething(){
rockItOldSchool();
logInfo("I'm the King around here now");
System.out.println("this new stuff rocks!!");
}
}

一切都很好,就像您期望的那样:

SpankingShiny shiny = new SpankingShiny();
shiny.executeSomething();

以上代码产生(如预期):

bustin' chops, old-school style
I'm the King around here now
this new stuff rocks!!

现在如您所见,'System.out.println()' 忠实地打印了所需的输出。但我希望用记录器替换“System.out.println()”。

问题:

我无法让 CGLIB 代理拦截“logInfo(string)”方法并让它通过记录器打印出我想要的消息(顺便说一下,我已经完成了日志记录配置)。该方法调用“显然”没有命中代理。

代码:

public class SpankingShinyProxy implements MethodInterceptor{

private SpankingShiny realShiny;
private final Logger logger = Logger.getLogger(SpankingShinyProxy.class);

public SpankingShinyProxy(SpankingShiny realShiny) {
super();
this.realShiny = realShiny;
}

@Override
public Object intercept(Object proxyObj, Method proxyMethod, Object[] methodParams, MethodProxy methodProxy) throws Throwable {
String methodName = proxyMethod.getName();
if("logInfo".equals(methodName)){
logger.info(methodParams[0]);
}
return proxyMethod.invoke(realShiny, methodParams);
}

public static SpankingShiny createProxy(SpankingShiny realObj){
Enhancer e = new Enhancer();
e.setSuperclass(realObj.getClass());
e.setCallback(new SpankingShinyProxy(realObj));
SpankingShiny proxifiedObj = (SpankingShiny) e.create();
return proxifiedObj;
}
}

主要方法:

public static void main(String... args) {

SpankingShiny shiny = new SpankingShiny();
shiny.executeSomething();

SpankingShiny shinyO = SpankingShinyProxy.createProxy(shiny);
shinyO.executeSomething();
}

以上代码产生(不符合预期):

bustin' chops, old-school style
I'm the King around here now
this new stuff rocks!!
bustin' chops, old-school style
I'm the King around here now
this new stuff rocks!!

我哪里会出错?

谢谢!

最佳答案

我遇到了同样的问题。在我的例子中,realObj 本身就是一个代理(一个 Spring Bean - 一个 @Component)。

所以我要做的就是更改 .setSuperClass() 部分:

Enhancer e = new Enhancer();
e.setSuperclass(realObj.getClass());
e.setCallback(new SpankingShinyProxy(realObj));
SpankingShiny proxifiedObj = (SpankingShiny) e.create();

我改变了:

e.setSuperclass(realObj.getClass());

收件人:

e.setSuperclass(realObj.getClass().getSuperClass());

之所以可行,是因为如前所述,realObj.getClass() 本身就是一个 CGLIB 代理,并且该方法返回了一个由 CGLIB 生成的疯狂名称类,例如 a.b.c.MyClass$ $EnhancerBySpringCGLIB$$1e18666c。当我添加 .getSuperClass() 时,它返回了它应该首先返回的类。

关于java - CGLIB 无法拦截父类(super class)/超接口(interface)中的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19748853/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com