2

Maybe this is a question prone to be deleted, but just in case.

I've had a doubt lately while doing @EventListener annotated methods on my services if those methods should be included on the service's interface or not.

I mean, with a class like:

class FooServiceImpl implements FooService {
    @EventListener
    public void doSomethingWithEvent(ApplicationEvent event){
        // do something
    }
}

Should doSomethingWithEvent be included in FooService?

I think it shouldn't as the method is not meant to be directly invoked by any other instance but the one managing the events.

But, on the other hand, I would have a public method on my service that is not included on the interface, and for some reason, that smells bad to me (maybe it's just a habit).

So, what to do? Is there any convention regarding this?

Alfergon
  • 5,463
  • 6
  • 36
  • 56
  • It depends on whether you consider this service as required to react to these types of events or not. – M. Prokhorov Feb 07 '18 at 14:55
  • 1
    I'd do an own interface for `doSomethingWithEvent` and call it - like - `ApplicationEventAware`. All in all I think this is off topic as primarily opinion based. – Clijsters Feb 07 '18 at 15:00
  • Possible duplicate of [Where should @Service annotation be kept? Interface or Implementation?](https://stackoverflow.com/questions/16351780/where-should-service-annotation-be-kept-interface-or-implementation) – pvpkiran Feb 07 '18 at 15:03
  • @pvpkiran, not really a duplicate. `@Service` annotation means a different thing to `@EventListener` one. – M. Prokhorov Feb 07 '18 at 15:05
  • @M.Prokhorov In what way it is different, Spring handles it the same way. May be intrernals are different. But the answer to that questions holds good even for this – pvpkiran Feb 07 '18 at 15:06
  • @Clijsters, there is one point to having it in interface: "I want all conforming implementations of this service to react to this event in some way". Which is not a really compelling one, and can be solved in different ways, but still. – M. Prokhorov Feb 07 '18 at 15:07
  • @pvpkiran, it's not about how Spring handles something, it's about meaning you attach to a piece of text as a programmer. – M. Prokhorov Feb 07 '18 at 15:09
  • @M.Prokhorov Then this method is a strict part of your service (contract) and would fit to the interface. But I don't think this is good practice. I'd definitive go with the `*-Aware` approach. – Clijsters Feb 07 '18 at 15:09

2 Answers2

2

I would say this is primarily opinion based, because afaik there is no real convention for this question. I didn't flag your question, because I think it is a good one and because I'm not sure if it is on or off topic.


Just ask yourself the following question: Is doSomethingWithEvent() part of my service? Is it part of the contract, its consumers (classes which use FooService) are using?

Or to break it down: Is there any case where a method, which uses FooService should be able to call doSomethingWithEvent() directly?
I don't think so.

So, with this in mind, basically: No, you shouldn't include that method in your interface. Programming against interfaces means you provide interfaces to your consumers and they can talk to them wihtout needing to know its implementations. That means also there could be (imho should be) different implementations for one interface. Some might provide an EventListener, some won't provide one.

I personally would prefer to create an own interface - let's say ApplicationEventAware and implement this in FooServiceImpl. You will find this approach in Spring many times. For this case I would name my implementation EventAwareFooService, and avoid *Impl classes, because this is bad design in my personal opinion. (and some might call it an anti pattern)


There is already ApplicationListener<E extends ApplicationEvent> So why not just implementing that?

Clijsters
  • 4,031
  • 1
  • 27
  • 37
  • I'm not using that, as it's the "old" way of doing event listening https://spring.io/blog/2015/02/11/better-application-events-in-spring-framework-4-2 – Alfergon Feb 07 '18 at 15:18
  • Nothing there says _"old" way_, does it? Yeah new annotations are awesome but wouldn't a dedicated interface the best approach for your specific case? – Clijsters Feb 07 '18 at 15:31
  • @Alfergon I added some references and tried to make my statement more clear – Clijsters Feb 07 '18 at 15:51
  • Hi Clijsters, if you find that a question is **primarily opinion-based**, please flag it as such (or vote it as such when you are over 3,000 reputation), instead of answering it. POB questions are off-topic at Stack Overflow. – TylerH Mar 14 '18 at 17:18
  • If I where sure on that, I had flagged it. Im not sure whether this question is more on a best practice request or an opinion based question. – Clijsters Mar 14 '18 at 17:22
0

I don't believe that there is a convention regarding this. However, I agree that doSomethingWithEvent() shouldn't be included in FooService. It will be interesting to see other peoples opinions on this.

Clijsters
  • 4,031
  • 1
  • 27
  • 37
Three Legs
  • 23
  • 2
  • 11