0

A message is received on a channel, and is processed by a transformer. The output of the transformer is the following class, which is passed on to the next step in the flow:

public class DomainBean{

   public DomainBean process() {
      // code
      return this;
   }

}

Another bean has a @Transformer method which calls the process method on the bean above, as follows:

@Component
public class Handler {

    @Transformer
    public Object handle(Message<?> message) throws MessagingException {
        DomainBean domainBean = (DomainBean) message;
        domainBean.process();
        return domainBean ;
    }

}

Within the IntegrationFlow, the handle method is invoked as follows:

.transform(handler)

Ideally I would like to do away with the Handler bean class, and call domainBean.process() using an object method reference, as follows:

.transform(DomainBean::process)

When I try that, or .<DomainBean, DomainBean>transform(DomainBean::process) compiler complains that

Non-static method cannot be referenced from a static context

Is there anyway to make this work?

Thanks

user1052610
  • 4,440
  • 13
  • 50
  • 101

1 Answers1

0

Your question isn't clear. There is really this method in the IntegrationFlowDefinition:

 * Populate the {@link MessageTransformingHandler} instance for the provided {@link GenericTransformer}.
 * @param genericTransformer the {@link GenericTransformer} to populate.
 * @param <S> the source type - 'transform from'.
 * @param <T> the target type - 'transform to'.
 * @return the current {@link IntegrationFlowDefinition}.
 * @see MethodInvokingTransformer
 * @see LambdaMessageProcessor
 */
public <S, T> B transform(GenericTransformer<S, T> genericTransformer) {

Where that GenericTransformer really can be expressed as lambda or method reference and we have enough tests to confirm that. The code there looks like:

.transform("hello "::concat)
...
.<String, Integer>transform(Integer::parseInt)
...
.<String, String>transform(String::toUpperCase)
...
.<MessagingException,  Message<?>>transform(MessagingException::getFailedMessage)

Maybe your problem that you need add exact generics agrs to the method? Therefore this:

.<DomainBean, DomainBean>transform(DomainBean::process)

However what I see that your DomainBean.process() is void. This signature doesn't fit the transformer purpose. Yes, you can do the same with a lambda what you have in the Handler or another solution is to use .handle(). This one really can call void method and, to be honest, that is exactly what fits to your logic - there is no any transformation logic so far.

However when service method is void there is no any continuation after this method call in the flow. Such a .handle() must be the last one-way endpoint in the flow definition. The void is equal to the Outbound Channel Adapter.

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • Artem, thanks as always. Have updated the question with the error I get when trying to do as in your examples. – user1052610 Mar 12 '18 at 13:35
  • Yeah... I see now. Sorry. You have confused me with your wish to call that method via method reference. But since it's not a lambda for the context you would like to call, there is no way to handle it as method reference. Such a method must fit to the `GenericTransformer.transform()` signature. Therefore no `DomainBean::process` for your there. You can workaround it only with the `.transform(p -> { p.process(); return p; })` – Artem Bilan Mar 12 '18 at 13:40