阻止 Spring AOP 关闭我的流?
Prevent Spring AOP from closing my Stream?
我正在使用以下结构(简化):
@Component
class RuleProvider {
public Stream<String> getRules() {
return Stream.of("r1", "r2", "r3");
}
}
@Service
class RuleService {
@Autowired RuleProvider ruleProvider;
public void evaluateRules() {
ruleProvider.getRules().foreach(System.out::println);
}
}
并且我使用 Spring AOP 来执行日志记录。现在我想记录所有交给服务的规则。一般来说,应该这样做:
@Aspect
class LoggingAspect {
@AfterReturning(value="execution(* *..RuleProvider.getRules(*))",
returning="rules")
void logRules(JoinPoint jp, Stream<String> rules) {
Logger logger = LoggerFactory.getLogger(jp.getTarget().getClass());
rules.peek(rule -> logger.debug("evaluating {}", rule);
}
}
这应该有效 - 评估方面,注册 peek
中间操作,一旦执行 foreach()
终端操作,日志记录也应该完成。
但是,当我 运行 这样做时,Stream 似乎在方面 运行 之后关闭 - 我在服务方法中得到 "stream has already been operated upon or closed"。
为什么要关闭流?有什么我可以做的吗?
流没有关闭,但显然 "has already been operated on" 与错误消息所说的完全一样。考虑一下 peek
通常是如何使用的:
Stream.of(...)
.peek(...)
.other_operations(...);
请注意,other_operations() 作用于 由 peek() 编辑的流 return,而不作用于原始流。您对方面所做的类似于此:
Stream s = Stream.of(...);
s.peek(...);
s.other_operations(...);
解决此问题的方法是替换 return 值,例如通过使用 @Around
方面。
我正在使用以下结构(简化):
@Component
class RuleProvider {
public Stream<String> getRules() {
return Stream.of("r1", "r2", "r3");
}
}
@Service
class RuleService {
@Autowired RuleProvider ruleProvider;
public void evaluateRules() {
ruleProvider.getRules().foreach(System.out::println);
}
}
并且我使用 Spring AOP 来执行日志记录。现在我想记录所有交给服务的规则。一般来说,应该这样做:
@Aspect
class LoggingAspect {
@AfterReturning(value="execution(* *..RuleProvider.getRules(*))",
returning="rules")
void logRules(JoinPoint jp, Stream<String> rules) {
Logger logger = LoggerFactory.getLogger(jp.getTarget().getClass());
rules.peek(rule -> logger.debug("evaluating {}", rule);
}
}
这应该有效 - 评估方面,注册 peek
中间操作,一旦执行 foreach()
终端操作,日志记录也应该完成。
但是,当我 运行 这样做时,Stream 似乎在方面 运行 之后关闭 - 我在服务方法中得到 "stream has already been operated upon or closed"。
为什么要关闭流?有什么我可以做的吗?
流没有关闭,但显然 "has already been operated on" 与错误消息所说的完全一样。考虑一下 peek
通常是如何使用的:
Stream.of(...)
.peek(...)
.other_operations(...);
请注意,other_operations() 作用于 由 peek() 编辑的流 return,而不作用于原始流。您对方面所做的类似于此:
Stream s = Stream.of(...);
s.peek(...);
s.other_operations(...);
解决此问题的方法是替换 return 值,例如通过使用 @Around
方面。