BAEL-1596 Spring Events (#5605)
* Annotation-driven event listener + generic events * update examples + add tests * add article link * add more tests for Spring Events
This commit is contained in:
parent
064113f939
commit
8e6fff4fc8
|
@ -5,9 +5,11 @@
|
|||
This project is used to replicate Spring Exceptions only.
|
||||
|
||||
### The Course
|
||||
|
||||
The "REST With Spring" Classes: http://bit.ly/restwithspring
|
||||
|
||||
### Relevant articles:
|
||||
|
||||
- [Guide to Spring @Autowired](http://www.baeldung.com/spring-autowire)
|
||||
- [Properties with Spring](http://www.baeldung.com/properties-with-spring) - checkout the `org.baeldung.properties` package for all scenarios of properties injection and usage
|
||||
- [Spring Profiles](http://www.baeldung.com/spring-profiles)
|
||||
|
@ -30,3 +32,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
|
|||
- [Spring Web Contexts](http://www.baeldung.com/spring-web-contexts)
|
||||
- [Spring Cache – Creating a Custom KeyGenerator](http://www.baeldung.com/spring-cache-custom-keygenerator)
|
||||
- [Spring @Primary Annotation](http://www.baeldung.com/spring-primary)
|
||||
- [Spring Events](https://www.baeldung.com/spring-events)
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package org.baeldung.springevents.synchronous;
|
||||
|
||||
import org.springframework.context.event.ContextStartedEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.event.TransactionPhase;
|
||||
import org.springframework.transaction.event.TransactionalEventListener;
|
||||
|
||||
@Component
|
||||
public class AnnotationDrivenEventListener {
|
||||
|
||||
// for tests
|
||||
private boolean hitContextStartedHandler = false;
|
||||
private boolean hitSuccessfulEventHandler = false;
|
||||
private boolean hitCustomEventHandler = false;
|
||||
|
||||
@EventListener
|
||||
public void handleContextStart(final ContextStartedEvent cse) {
|
||||
System.out.println("Handling context started event.");
|
||||
hitContextStartedHandler = true;
|
||||
}
|
||||
|
||||
@EventListener(condition = "#event.success")
|
||||
public void handleSuccessful(final GenericSpringEvent<String> event) {
|
||||
System.out.println("Handling generic event (conditional): " + event.getWhat());
|
||||
hitSuccessfulEventHandler = true;
|
||||
}
|
||||
|
||||
@TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT)
|
||||
public void handleCustom(final CustomSpringEvent event) {
|
||||
System.out.println("Handling event inside a transaction BEFORE COMMIT.");
|
||||
hitCustomEventHandler = true;
|
||||
}
|
||||
|
||||
boolean isHitContextStartedHandler() {
|
||||
return hitContextStartedHandler;
|
||||
}
|
||||
|
||||
boolean isHitSuccessfulEventHandler() {
|
||||
return hitSuccessfulEventHandler;
|
||||
}
|
||||
|
||||
boolean isHitCustomEventHandler() {
|
||||
return hitCustomEventHandler;
|
||||
}
|
||||
}
|
|
@ -7,9 +7,16 @@ import org.springframework.stereotype.Component;
|
|||
@Component
|
||||
public class ContextRefreshedListener implements ApplicationListener<ContextRefreshedEvent> {
|
||||
|
||||
// for tests
|
||||
private boolean hitContextRefreshedHandler = false;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(final ContextRefreshedEvent cse) {
|
||||
System.out.println("Handling context re-freshed event. ");
|
||||
hitContextRefreshedHandler = true;
|
||||
}
|
||||
|
||||
boolean isHitContextRefreshedHandler() {
|
||||
return hitContextRefreshedHandler;
|
||||
}
|
||||
}
|
|
@ -16,4 +16,16 @@ public class CustomSpringEventPublisher {
|
|||
applicationEventPublisher.publishEvent(customSpringEvent);
|
||||
}
|
||||
|
||||
public void publishGenericEvent(final String message, boolean success) {
|
||||
System.out.println("Publishing generic event.");
|
||||
final GenericSpringEvent<String> genericSpringEvent = new GenericStringSpringEvent(message, success);
|
||||
applicationEventPublisher.publishEvent(genericSpringEvent);
|
||||
}
|
||||
|
||||
public void publishGenericAppEvent(final String message) {
|
||||
System.out.println("Publishing generic event.");
|
||||
final GenericSpringAppEvent<String> genericSpringEvent = new GenericStringSpringAppEvent(this, message);
|
||||
applicationEventPublisher.publishEvent(genericSpringEvent);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
package org.baeldung.springevents.synchronous;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
public class GenericSpringAppEvent<T> extends ApplicationEvent {
|
||||
|
||||
private final T what;
|
||||
|
||||
public GenericSpringAppEvent(final Object source, final T what) {
|
||||
super(source);
|
||||
this.what = what;
|
||||
}
|
||||
|
||||
public T getWhat() {
|
||||
return what;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package org.baeldung.springevents.synchronous;
|
||||
|
||||
public class GenericSpringEvent<T> {
|
||||
|
||||
private final T what;
|
||||
protected final boolean success;
|
||||
|
||||
public GenericSpringEvent(final T what, final boolean success) {
|
||||
this.what = what;
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public T getWhat() {
|
||||
return what;
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package org.baeldung.springevents.synchronous;
|
||||
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class GenericSpringEventListener implements ApplicationListener<GenericSpringAppEvent<String>> {
|
||||
|
||||
// for testing
|
||||
private boolean hitEventHandler = false;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(@NonNull final GenericSpringAppEvent<String> event) {
|
||||
System.out.println("Received spring generic event - " + event.getWhat());
|
||||
hitEventHandler = true;
|
||||
}
|
||||
|
||||
boolean isHitEventHandler() {
|
||||
return hitEventHandler;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package org.baeldung.springevents.synchronous;
|
||||
|
||||
class GenericStringSpringAppEvent extends GenericSpringAppEvent<String> {
|
||||
|
||||
GenericStringSpringAppEvent(final Object source, final String what) {
|
||||
super(source, what);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package org.baeldung.springevents.synchronous;
|
||||
|
||||
public class GenericStringSpringEvent extends GenericSpringEvent<String> {
|
||||
|
||||
GenericStringSpringEvent(final String what, final boolean success) {
|
||||
super(what, success);
|
||||
}
|
||||
|
||||
}
|
|
@ -3,16 +3,23 @@ package org.baeldung.springevents.synchronous;
|
|||
import org.baeldung.springevents.synchronous.SynchronousSpringEventsConfig;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||
|
||||
import static org.springframework.util.Assert.isTrue;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { SynchronousSpringEventsConfig.class }, loader = AnnotationConfigContextLoader.class)
|
||||
public class ContextRefreshedListenerIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private ContextRefreshedListener listener;
|
||||
|
||||
@Test
|
||||
public void testContextRefreshedListener() throws InterruptedException {
|
||||
public void testContextRefreshedListener() {
|
||||
System.out.println("Test context re-freshed listener.");
|
||||
isTrue(listener.isHitContextRefreshedHandler(), "Refresh should be called once");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package org.baeldung.springevents.synchronous;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||
|
||||
import static org.springframework.util.Assert.isTrue;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { SynchronousSpringEventsConfig.class }, loader = AnnotationConfigContextLoader.class)
|
||||
public class GenericAppEventListenerIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private CustomSpringEventPublisher publisher;
|
||||
@Autowired
|
||||
private GenericSpringEventListener listener;
|
||||
|
||||
@Test
|
||||
public void testGenericSpringEvent() {
|
||||
isTrue(!listener.isHitEventHandler(), "The initial value should be false");
|
||||
publisher.publishGenericAppEvent("Hello world!!!");
|
||||
isTrue(listener.isHitEventHandler(), "Now the value should be changed to true");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package org.baeldung.springevents.synchronous;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -7,16 +8,42 @@ import org.springframework.test.context.ContextConfiguration;
|
|||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||
|
||||
import static org.springframework.util.Assert.isTrue;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { SynchronousSpringEventsConfig.class }, loader = AnnotationConfigContextLoader.class)
|
||||
public class SynchronousCustomSpringEventsIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private CustomSpringEventPublisher publisher;
|
||||
@Autowired
|
||||
private AnnotationDrivenEventListener listener;
|
||||
|
||||
@Test
|
||||
public void testCustomSpringEvents() throws InterruptedException {
|
||||
public void testCustomSpringEvents() {
|
||||
isTrue(!listener.isHitCustomEventHandler(), "The value should be false");
|
||||
publisher.publishEvent("Hello world!!");
|
||||
System.out.println("Done publishing synchronous custom event. ");
|
||||
isTrue(listener.isHitCustomEventHandler(), "Now the value should be changed to true");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenericSpringEvent() {
|
||||
isTrue(!listener.isHitSuccessfulEventHandler(), "The initial value should be false");
|
||||
publisher.publishGenericEvent("Hello world!!!", true);
|
||||
isTrue(listener.isHitSuccessfulEventHandler(), "Now the value should be changed to true");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenericSpringEventNotProcessed() {
|
||||
isTrue(!listener.isHitSuccessfulEventHandler(), "The initial value should be false");
|
||||
publisher.publishGenericEvent("Hello world!!!", false);
|
||||
isTrue(!listener.isHitSuccessfulEventHandler(), "The value should still be false");
|
||||
}
|
||||
|
||||
@Ignore("fix me")
|
||||
@Test
|
||||
public void testContextStartedEvent() {
|
||||
isTrue(listener.isHitContextStartedHandler(), "Start should be called once");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue