gpt4 book ai didi

java - Advice 从具体非泛型类中的泛型抽象类继承方法

转载 作者:行者123 更新时间:2023-11-30 12:08:31 28 4
gpt4 key购买 nike

例如我有如下界面

public interface Converter<I, O> {
public O convert(I input);
}

实现该接口(interface)的抽象类

public abstract class AbstractIntegerConverter<T> implements Converter<T, Integer> {

public Integer convert(T input) {
// convert anything to int
}

public abstract Integer defaultValue();
}

及具体实现

@Component
public class StringToIntegerConverter extends AbstractIntegerConverter<String> {

@Override
public Integer defaultValue() {
// implementation
}
}

我想建议所有将 String 转换为任何内容的方法。我创建了以下方面

@Aspect
@Component
public class ConverterAspect {

@Around("execution(* *..*.Converter+.convert(String))")
public Object adviceStringConverter(ProceedingJoinPoint joinPoint) throws Throwable {
// logic
}
}

这是行不通的。 Spring 不会为 StringToIntegerConverter 类创建代理。但是,如果我重写抽象类中的 convert(String input) 方法,它将开始工作并且 Spring 成功地为 StringToIntegerConverter 创建代理并执行所有需要的逻辑。

@Component
public class StringToIntegerConverter extends AbstractIntegerConverter<String> {

@Override
public Integer convert(String input) {
return super.convert(input);
}

@Override
public Integer defaultValue() {
// implementation
}
}

为什么会这样?有什么方法可以定义切入点,这样我就不需要重写 convert(String input) 方法了吗?

最佳答案

AbstractIntegerConverter 中,方法签名不是 public Integer convert(String input) 而是 public Integer convert(T input),因此您的切入点* *..*.Converter+.convert(String) 不匹配。改为使用 Object* 并通过 args() 验证运行时类型,而不是使用编译时签名:

@Around("execution(* *..Converter+.convert(*)) && args(input)")
public Object adviceStringConverter(ProceedingJoinPoint joinPoint, String input) throws Throwable {
System.out.println(joinPoint);
return joinPoint.proceed();
}

使用我添加的日志行,您将在控制台上看到如下内容:

execution(Integer de.scrum_master.app.AbstractIntegerConverter.convert(Object))

看到了吗? convert(Object),而不是 convert(String),因此不匹配。

P.S.:这是一个有趣的问题,不像大多数 AspectJ 或 Spring AOP 问题那么无聊。所以谢谢你。 :-)


更新:

关于您的后续问题,这是 javap -s 打印的内容(方面已停用):

javap -s AbstractIntegerConverter.class

Compiled from "AbstractIntegerConverter.java"
public abstract class de.scrum_master.app.AbstractIntegerConverter<T> implements de.scrum_master.app.Converter<T, java.lang.Integer> {
public de.scrum_master.app.AbstractIntegerConverter();
descriptor: ()V

public java.lang.Integer convert(T);
descriptor: (Ljava/lang/Object;)Ljava/lang/Integer;

public abstract java.lang.Integer defaultValue();
descriptor: ()Ljava/lang/Integer;

public java.lang.Object convert(java.lang.Object);
descriptor: (Ljava/lang/Object;)Ljava/lang/Object;
}

看到了吗?签名是 convert(Object) 正如我方面的日志输出也显示的那样。

javap -s StringToIntegerConverter.class

Compiled from "StringToIntegerConverter.java"
public class de.scrum_master.app.StringToIntegerConverter extends de.scrum_master.app.AbstractIntegerConverter<java.lang.String> {
public de.scrum_master.app.StringToIntegerConverter();
descriptor: ()V

public java.lang.Integer defaultValue();
descriptor: ()Ljava/lang/Integer;
}

具体转换器类中没有convert(String)convert(whatever) 方法。

你现在相信我了吗?

关于java - Advice 从具体非泛型类中的泛型抽象类继承方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54315147/

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