【发布时间】:2022-02-02 10:00:30
【问题描述】:
我想在我的 Spring Boot 应用程序中添加用于日志记录的 AOP。但它似乎以意想不到的方式改变了我的应用程序的行为。
例如,我的应用程序有一个方法doThis(),它创建了一个MyObject 实例:
MyObject myObect = doThis(); // a non-null myObject is returned from doThis()
效果很好,myObject 按预期填充了从doThis() 返回的实例。但我希望 doThis() 方法也通过 AOP 记录一些消息。
然后我添加以下方面类:
@Aspect
public class LoggingAspect {
private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);
@Around("execution(* my.service.package.*.*(..))")
public void log(ProceedingJoinPoint joinPoint) throws Throwable {
logger.info("before");
joinPoint.proceed();
logger.info("after");
}
}
而且我还添加了这个配置类:
@Configuration
@ComponentScan(basePackages = "my.service.package")
@EnableAspectJAutoProxy
public class AppConfig {
@Bean
public LoggingAspect aspect() {
return new LoggingAspect();
}
}
但是,现在当我运行我的应用程序时,确实会出现日志记录语句,正如预期的那样 - 但现在同样的 doThis() 方法显然返回了一个空对象:
MyObject myObect = doThis(); // myObject is now unexplainedly null
但事实并非如此!我的意思是当我在doThis() 的最后一行设置断点时,它即将返回的MyObject 实例非常明显not null。它已在doThis() 方法中创建和填充。那么它去哪儿了?为什么myObject 没有在doThis() 明确返回非空MyObject 实例时被填充?
似乎方面以某种方式使从doThis() 返回的对象无效。有没有人见过这个?有什么办法解决吗?
我相信我的 execution 语句中的第一个 * 应该表明被拦截的方法可以具有任何返回类型。但是,我截获的方法的返回值似乎以某种方式更改为 null。
我正在研究如何根据评论创建一个“最小的可重现示例”,我将在此处添加,但这似乎是一个相当标准的 AOP 用例,因此在此期间将其扔掉以防有人可能有一些见解。
【问题讨论】:
-
请提供minimal reproducible example。你确认
myService.doThis()返回null了吗? -
myService.doThis()实际上返回一个实体对象。这方面似乎有效。但是当我实际尝试保存返回的实体对象时它不起作用。 -
我要关闭您的错误消息“实体不能为空”
-
有趣的是 doThis() 确实返回 null - 但只有在我添加 Aspect 代码之后。
-
请提供minimal reproducible example,以便我们了解原因。
标签: java spring aop aspectj spring-aop