userspaced
userspaced

Reputation: 1393

Spring, Reactor and @Consumer

I have a Spring Boot project that uses reactor for asynchronous tasks. I have began the task of upgrading the project to Spring Boot 1.3.1. As a side effect, it appears that it's using a new version of reactor. I am trying to figure out how to get it to work with the new reactor. I was using the @Consumer and @Selector annotations to tell it what classes and methods to use for an event like so:

@Consumer
public class MyReceiver {

  @Selector(value = "someEvent", reactor = "@rootReactor")
  public void receiveEvent(SomeObject someObject) {
    ...
  }

}

I was previously notifying the receiver by doing this in a service class:

@Autowired
Reactor rootReactor;

public void someMethod() {
  ...
  rootReactor.notify("someEvent", Event.wrap(someObject));
}

I have figured out that I need to change the rootReactor stuff to this:

@Autowired
EventBus eventBus;

public void someMethod() {
  ...
  eventBus.notify("someEvent", Event.wrap(someObject));
}

But I'm not sure what I need to do on the consumer side. @Selector no longer supports the reactor attribute, so you can change it to eventBus, but what is the detault event bus named now? When I tried @Selector with ONLY the value attribute I started getting an NPE.

Upvotes: 2

Views: 1626

Answers (3)

wz2b
wz2b

Reputation: 1025

I just tried this with reactor-spring-messaging 2.0.7.RELEASE and it works even if the autowired field is private. The field does indeed have to be named exactly "eventBus" or, if you name it something else, you have to specify its alternative name in the @Selector annotation.

If you prefer, you can @Autowire or @Inject the EventBus into your constructor and assign a property. This works just fine, and has the advantage that the IDE isn't angry at you about declaring an otherwise-unused field::

  private final EventBus eventBus;

  @Autowired
  private SomeObject(EventBus eventBus) {
    this.eventBus = eventBus;
  }

but the same rules about the field name apply. I tend to prefer constructor injection over injected fields.

Upvotes: 1

Sean Connolly
Sean Connolly

Reputation: 5803

In moving from Reactor v1.x to Reactor v2.x, Reactor was renamed to EventBus which is reflected in the @Selector annotation.

Your @Selector goes from..

@Selector(value = "someEvent", reactor = "@rootReactor")

to..

@Selector(value = "someEvent", eventBus = "@rootReactor")

Upvotes: 0

Jan Galinski
Jan Galinski

Reputation: 11993

Your consumer must define an autowired, public (!) attribute of type eventBus. The consumer scans for it and register to the bus. Not a very nice solution, but it should work

@Consumer
public class MyReceiver {
   @Autowired
   public EventBus eventBus;

   @Selector(value = "someEvent", reactor = "@rootReactor")
   public void receiveEvent(SomeObject someObject) {
       ...
   }
}

}

Upvotes: 0

Related Questions