Java 当一个@Around通知未继续时,通知优先级问题

Java 当一个@Around通知未继续时,通知优先级问题,java,annotations,spring-aop,Java,Annotations,Spring Aop,更新以使用附加信息重新表述问题 我们有两个注释: CustomLogging PollableStreamListener 两者都是通过SpringAOP使用方面实现的 CustomLogging注释: @Target(ElementType.METHOD) @保留(RetentionPolicy.RUNTIME) public@interface自定义日志记录{ } CustomLoggingAspectclass: @方面 @组成部分 @Slf4j @顺序(值=1) 公共类Custom

更新以使用附加信息重新表述问题

我们有两个注释:

  • CustomLogging
  • PollableStreamListener
两者都是通过SpringAOP使用方面实现的

CustomLogging
注释:

@Target(ElementType.METHOD)
@保留(RetentionPolicy.RUNTIME)
public@interface自定义日志记录{
}
CustomLoggingAspect
class:

@方面
@组成部分
@Slf4j
@顺序(值=1)
公共类CustomLoggingAspect{
@在(“@注释(自定义日志记录)”之前
public void addCustomLogging(CustomLogging CustomLogging){
log.info(“记录一些信息”);
}
}
PollableStreamListener
注释:

@Target(ElementType.METHOD)
@保留(RetentionPolicy.RUNTIME)
public@interface PollableStreamListener{
}
PollableStreamListenerAspect
class:

@方面
@组成部分
@Slf4j
公共类PollableStreamListenerAspect{
private final executor服务executor=Executors.newFixedThreadPool(1);
private=false;
@大约(value=“@annotation(pollableStreamListener)&&args(dataCapsule,…”)
public void receiveMessage(ProceedingJoinPoint-joinPoint,
PollableStreamListener PollableStreamListener,对象数据胶囊){
if(信息的数据胶囊实例){
消息消息=(消息)数据胶囊;
AcknowledgementCallback=StaticMessageHeaderAccessor
.GetAcknowledgementCallback(消息);
callback.noAutoAck();
如果(!暂停){
//单独的线程没有处理上一条消息,因此处理此消息:
Runnable Runnable=()->{
试一试{
暂停=真;
//调用方法来处理此Kafka消息
joinPoint.procedure();
回调。确认(状态。接受);
}捕获(可丢弃的e){
回调.确认(状态.拒绝);
抛出新的PollableStreamListenerException(e);
}最后{
暂停=错误;
}
};
执行人提交(可运行);
}否则{
//单独的线程正忙于处理前一条消息,因此请将此消息重新排队,以便以后使用:
回拨.确认(状态.重新请求);
log.info(“重新排队”);
}
}
}
}
我们有一个名为CleanupController的类,它根据计划定期执行

CleanupController
class:

@Scheduled(fixedDelayString=“${app.pollable consumer.time interval}”)
public void pollfordelectionrequest(){
log.trace(“轮询新消息”);
cleanupInput.poll(cleanupSubmissionService::SubmitDelete);
}
当调度执行时,它调用另一个类中的方法,该类使用
PollableStreamListener
CustomLogging
进行注释。我添加了一个
Thread.sleep()
,以模拟需要一段时间才能执行的方法

@PollableStreamListener
@自定义日志记录
公共作废提交删除(收到消息){
试一试{
log.info(“开始处理”);
睡眠(10000);
日志信息(“已完成处理”);
}捕获(例外e){
日志信息(“错误”,e);
}
}
我面临的问题是,每当我们使用
@Schedule
轮询新消息时,
CustomLogging
生成的输出都会打印出来,但我只希望在实际执行带注释的方法时打印它(这可能发生在现在,也可能发生在将来,具体取决于当前是否正在处理另一条消息)。这会导致日志消息混乱,因为这意味着消息现在正在处理,而事实上它已重新排队等待将来执行

是否有某种方法可以使这些注释一起很好地工作,从而使
CustomLogging
输出仅在注释方法执行时发生


更新以在
PollableStreamListener
上使用
@Order

根据@dunni的建议,我对上面的原始示例做了以下更改

在PollableStreamListenerSpect上设置1的顺序:

@方面
@组成部分
@Slf4j
@顺序(值=1)
公共类PollableStreamListenerAspect{
...
}
CustomLoggingAspect
的订单增加到2:

@方面
@组成部分
@Slf4j
@顺序(值=2)
公共类CustomLoggingAspect{
...
}
我发现在做了这些更改之后,轮询根本无法检测到新的请求。正是
PollableStreamListenerAspect
上的更改导致了这个问题(我注释掉了那一行并重新运行了它,事情的表现与以前一样)


更新以在
PollableStreamListener上使用
@Order(value=Ordered.最高优先级)

我已更新了
PollableStreamListener
以使用
最高优先级
,并更新了
@前后的
值:

@方面
@组成部分
@Slf4j
@顺序(值=顺序。最高优先级)
公共类PollableStreamListenerAspect{
private final executor服务executor=Executors.newFixedThreadPool(1);
private=false;
@大约(value=“@annotation(au.com.brolly.commons.stream.PollableStreamListener)”)
public void receiveMessage(ProceedingJoinPoint-joinPoint){
如果(!暂停){
//单独的线程没有处理上一条消息,因此处理此消息:
Runnable Runnable=()->{
试一试{
暂停=真;
//调用方法来处理此Kafka消息
joinPoint.procedure();
}捕获(可丢弃的e){
e、 printStackTrace();
抛出新的PollableStreamListenerException(e);
}最后{
2021-04-22 10:38:00,055 ERROR [scheduling-1] org.springframework.core.log.LogAccessor: org.springframework.messaging.MessageHandlingException: nested exception is java.lang.IllegalStateException: Required to bind 2 arguments, but only bound 1 (JoinPointMatch was NOT bound in invocation), failedMessage=GenericMessage...
    at org.springframework.cloud.stream.binder.DefaultPollableMessageSource.doHandleMessage(DefaultPollableMessageSource.java:330)
    at org.springframework.cloud.stream.binder.DefaultPollableMessageSource.handle(DefaultPollableMessageSource.java:361)
    at org.springframework.cloud.stream.binder.DefaultPollableMessageSource.poll(DefaultPollableMessageSource.java:219)
    at org.springframework.cloud.stream.binder.DefaultPollableMessageSource.poll(DefaultPollableMessageSource.java:200)
    at org.springframework.cloud.stream.binder.DefaultPollableMessageSource.poll(DefaultPollableMessageSource.java:68)
    at xyx.pollForDeletionRequest(CleanupController.java:35)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
    at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305)
    at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.IllegalStateException: Required to bind 2 arguments, but only bound 1 (JoinPointMatch was NOT bound in invocation)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.argBinding(AbstractAspectJAdvice.java:596)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:624)
    at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:72)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692)
    at xyz.CleanupSubmissionServiceImpl$$EnhancerBySpringCGLIB$$8737f6f8.submitDeletion(<generated>)
    at org.springframework.cloud.stream.binder.DefaultPollableMessageSource.doHandleMessage(DefaultPollableMessageSource.java:327)
    ... 17 more