RestController 的父级 class 的切面方法不会触发通知逻辑
Aspect method of a parent class of a RestController does not trigger advice logic
我有一些我真的很想在其上使用方面的结构。我想让我的 RestController 继承自 class,它会产生特殊的日志记录方法
- 记录到标准的 logback 输出
- 向对日志进行处理的服务发出 http 请求
消息以及(由方面完成)
我创建了一个注释,用于标记我想要切面的方法,因此切入点无法过滤它。特殊情况是此方法在 RestController 的父级 class 中声明。
方面不是 运行 即使 IntelliJ 将方法标记为方面正在使用,这告诉我切入点必须工作?
请查看我的代码并检查我可能遗漏了什么以使其正常工作。
ApplicationClass
@SpringBootApplication
@ComponentScan("com.xetra.experimental")
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AopTryoutApplication {
public static void main(String[] args) {
SpringApplication.run(AopTryoutApplication.class, args);
}
}
RestController
@RestController
public class Endpoint extends SimpleLogger {
@GetMapping("/endpoint")
public void doStuff(){
log("foo");
}
}
RestController 的父级 class
public class SimpleLogger implements EndpointLogger{
@AspectAnnotation
public void log(String msg) {
System.out.println(msg);
}
}
父接口class(听说方面方法需要接口)
public interface EndpointLogger {
void log(String msg);
}
注解我的方面应该指向
@Inherited
public @interface AspectAnnotation {
}
Spring AOP方面
@Component
@Aspect
public class TestAspect {
@Pointcut("@annotation(com.xetra.experimental.aoptryout.AspectAnnotation)")
public void methods() {
}
@Before("methods()")
public void beforeMethodExecution(JoinPoint jp) {
System.out.println("Aspect ran!!!!");
}
}
Due to the proxy-based nature of Spring’s AOP framework, calls within the target object are by definition not intercepted.
您可以找到更多 here。
对 log
方法的调用未被拦截,因为它是从属于同一目标对象的 doStuff
方法发出的。
现在,任何对 log
方法的调用都将被拦截,只要它是从另一个对象(不是同一个目标对象)外部进行的。
问题
因此,如果我在端点内将 SimpleLogger 用作组件而不是父组件 class,它会工作吗?
是的,你是对的!
有什么方法可以让它正常工作吗?喜欢使用 AspectJ 而不是 Spring AOP?
您可以使用 AspectJ 的 source weaving 使其工作。 Here,是一个工作示例。
我有一些我真的很想在其上使用方面的结构。我想让我的 RestController 继承自 class,它会产生特殊的日志记录方法
- 记录到标准的 logback 输出
- 向对日志进行处理的服务发出 http 请求 消息以及(由方面完成)
我创建了一个注释,用于标记我想要切面的方法,因此切入点无法过滤它。特殊情况是此方法在 RestController 的父级 class 中声明。
方面不是 运行 即使 IntelliJ 将方法标记为方面正在使用,这告诉我切入点必须工作?
请查看我的代码并检查我可能遗漏了什么以使其正常工作。
ApplicationClass
@SpringBootApplication
@ComponentScan("com.xetra.experimental")
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AopTryoutApplication {
public static void main(String[] args) {
SpringApplication.run(AopTryoutApplication.class, args);
}
}
RestController
@RestController
public class Endpoint extends SimpleLogger {
@GetMapping("/endpoint")
public void doStuff(){
log("foo");
}
}
RestController 的父级 class
public class SimpleLogger implements EndpointLogger{
@AspectAnnotation
public void log(String msg) {
System.out.println(msg);
}
}
父接口class(听说方面方法需要接口)
public interface EndpointLogger {
void log(String msg);
}
注解我的方面应该指向
@Inherited
public @interface AspectAnnotation {
}
Spring AOP方面
@Component
@Aspect
public class TestAspect {
@Pointcut("@annotation(com.xetra.experimental.aoptryout.AspectAnnotation)")
public void methods() {
}
@Before("methods()")
public void beforeMethodExecution(JoinPoint jp) {
System.out.println("Aspect ran!!!!");
}
}
Due to the proxy-based nature of Spring’s AOP framework, calls within the target object are by definition not intercepted.
您可以找到更多 here。
对 log
方法的调用未被拦截,因为它是从属于同一目标对象的 doStuff
方法发出的。
现在,任何对 log
方法的调用都将被拦截,只要它是从另一个对象(不是同一个目标对象)外部进行的。
问题
因此,如果我在端点内将 SimpleLogger 用作组件而不是父组件 class,它会工作吗?
是的,你是对的!
有什么方法可以让它正常工作吗?喜欢使用 AspectJ 而不是 Spring AOP?
您可以使用 AspectJ 的 source weaving 使其工作。 Here,是一个工作示例。