例如,我具有以下界面
public interface Converter<I, O> {
public O convert(I input);
}
实现此接口的抽象类
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)
方法了?
答案 0 :(得分:0)
在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)
方法。
你现在相信我吗?