Browse Source

Regression test for duplicate firing of proxied application listeners

ApplicationContextEventTests.eventForSelfInjectedProxiedListenerFiredOnlyOnce
relates to and reproduces #28283.
pull/31407/head
Alexander Kriegisch 1 year ago committed by Juergen Hoeller
parent
commit
86d52a677a
  1. 23
      spring-context/src/test/java/org/springframework/context/event/ApplicationContextEventTests.java
  2. 17
      spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyApplication.java
  3. 15
      spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyAspect.java
  4. 12
      spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEvent.java
  5. 20
      spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEventListener.java
  6. 15
      spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEventPublisher.java

23
spring-context/src/test/java/org/springframework/context/event/ApplicationContextEventTests.java

@ -40,6 +40,11 @@ import org.springframework.context.ApplicationEventPublisher; @@ -40,6 +40,11 @@ import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.PayloadApplicationEvent;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.event.test.self_inject.MyApplication;
import org.springframework.context.event.test.self_inject.MyEventListener;
import org.springframework.context.event.test.self_inject.MyEventPublisher;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.context.support.StaticMessageSource;
@ -271,6 +276,24 @@ public class ApplicationContextEventTests extends AbstractApplicationEventListen @@ -271,6 +276,24 @@ public class ApplicationContextEventTests extends AbstractApplicationEventListen
assertThat(listener1.seenEvents).hasSize(2);
}
/**
* Regression test for <a href="https://github.com/spring-projects/spring-framework/issues/28283">issue 28283</a>,
* where event listeners proxied due to e.g.
* <ul>
* <li>{@code @Transactional} annotations in their methods or</li>
* <li>being targeted by aspects</li>
* </ul>
* were added to the list of application listener beans twice (both proxy and unwrapped target).
*/
@Test
public void eventForSelfInjectedProxiedListenerFiredOnlyOnce() {
String basePackage = MyApplication.class.getPackageName();
AbstractApplicationContext context = new AnnotationConfigApplicationContext(basePackage);
context.getBean(MyEventPublisher.class).publishMyEvent("hello");
assertThat(MyEventListener.eventCount).isEqualTo(1);
context.close();
}
@Test
public void testEventPublicationInterceptor() throws Throwable {
MethodInvocation invocation = mock();

17
spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyApplication.java

@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
package org.springframework.context.event.test.self_inject;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.support.AbstractApplicationContext;
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class MyApplication {
public static void main(String[] args) {
try (AbstractApplicationContext context = new AnnotationConfigApplicationContext("org.springframework.context.event.test.self_inject")) {
context.getBean(MyEventPublisher.class).publishMyEvent("hello");
assert MyEventListener.eventCount == 1 : "event listener must fire exactly once";
}
}
}

15
spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyAspect.java

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
package org.springframework.context.event.test.self_inject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class MyAspect {
@Before("within(org.springframework.context.event.test.self_inject.MyEventListener)")
public void myAdvice(JoinPoint joinPoint) {
//System.out.println(joinPoint);
}
}

12
spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEvent.java

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
package org.springframework.context.event.test.self_inject;
import org.springframework.context.ApplicationEvent;
public class MyEvent extends ApplicationEvent {
private String message;
public MyEvent(Object source, String message) {
super(source);
this.message = message;
}
}

20
spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEventListener.java

@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
package org.springframework.context.event.test.self_inject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component
public class MyEventListener implements ApplicationListener<MyEvent> {
public static int eventCount;
@Autowired // use '-Dspring.main.allow-circular-references=true' in Spring Boot >= 2.6.0
//@Lazy // with '@Lazy', the problem does not occur
private MyEventListener eventDemoListener;
@Override
public void onApplicationEvent(MyEvent event) {
//System.out.println("Event: " + event);
eventCount++;
}
}

15
spring-context/src/test/java/org/springframework/context/event/test/self_inject/MyEventPublisher.java

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
package org.springframework.context.event.test.self_inject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
@Component
public class MyEventPublisher {
@Autowired
private ApplicationEventPublisher eventPublisher;
public void publishMyEvent(String message) {
eventPublisher.publishEvent(new MyEvent(this, message));
}
}
Loading…
Cancel
Save