Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Integration @ServiceActivator on a Java 8 default interface method

I'd like to use the @ServiceActivator annotation on a Java 8 default interface method. This default method will delegate to another method of this interface depending on business rules.

public interface MyServiceInterface {

    @ServiceActivator
    public default void onMessageReceived(MyPayload payload) {
        if(payload.getAction() == MyServiceAction.MY_METHOD) {
            ...
            myMethod(...);
        }
    }

    public void myMethod(...);
}

This interface is then implemented by a Spring @Service class:

@Service
public class MyService implements MyServiceInterface {

    public void myMethod(...) {
        ...
    }
}

When executing the code, this does not work!

I can only get it to work to remove the @ServiceActivator annotation from the default method, and override that default method in my @Service class and delegate to the super method:

@Service
public class MyWorkingService implements MyServiceInterface {

    @ServiceActivator
    @Override
    public void onMessageReceived(MyPayload payload) {
        MyServiceInterface.super.onMessageReceived(payload);
    }

    public void myMethod(...) {
        ...
    }
}

Overriding a default method neglects the purpose of a default method.

Is there another way to implement this scenario in a clean manner?

like image 276
Stefaan Neyts Avatar asked Mar 16 '15 11:03

Stefaan Neyts


1 Answers

This doesn't work now, because Spring Integration relies on the ReflectionUtils.doWithMethods, which uses ReflectionUtils.getDeclaredMethods and the last one just does this clazz.getDeclaredMethods(), which doesn't return those default methods on the interface.

Feel free to raise an JIRA issue against Spring Framework to consider that option.

In meantime, right, there is no other choice unless to override that method.

like image 184
Artem Bilan Avatar answered Oct 12 '22 23:10

Artem Bilan