简体   繁体   中英

Understanding an Axon library's Java Idiom involving Interface method and Lambda expression for configuration of TokenStore

I have a question on Java Syntax on lambda expressions and the java.util.function.Function Object. Also probably Spring Dependency Injection. It is an idiom that I don't know and I hope somebody can explain it to me. I know (probably only the basics) about that idiom of generic @FunctionalInterface(s) and "implementations" through lambda expressions. This use-case seems similar, but still different.

In the example, the Function<T,R> -Object is the Type of a parameter of a method of a configuration class with a parameter name. The argument is the lambda expression config -> tokenStore .

But please look at the information provided below. Here are my questions.

  1. What config is passed as the argument? There is no "config" symbol there. So I guess it is injected by the Spring IoC Container.
  2. And what it obviously returns is the symbol tokenStore that is bound to an org.axonframework.eventhandling.tokenstore.TokenStore Instance created by the JpaTokenStore#build method. There is no connection to the config argument. Or is there?
  3. To sum it up: Just "Why?" Why are you passing a lambda expression where there is no obvious (to me) connection between the argument and the return value and why are you passing a Function-placeholder to an Interface-method - how do you call it... the head of the method? Ultimately: What is that doing because to someone like me who obviously doesn't know the idiom it looks like the answer is: nothing?

So, there is this example on how to configure a TokenStore from the Axon Framework and I would like to understand how it works:

public class AxonConfig { 
    // ...
    public void registerTokenStore(EventProcessingConfigurer processingConfigurer) {
        TokenStore tokenStore = JpaTokenStore.builder()
                                             // …
                                             .build();
    
        processingConfigurer.registerTokenStore(config -> tokenStore);
    }
}

source: https://docs.axoniq.io/reference-guide/axon-framework/events/event-processors/streaming#token-store

And here is the source code for the EventProcessingConfigurer#registerTokenStore (GitHub) method.

public interface EventProcessingConfigurer {

// ...

   EventProcessingConfigurer registerTokenStore(Function<Configuration, TokenStore> tokenStore);

// ...

}

btw: can I pass in an argument for the code block to tell the forum software which language it is?

Thanks vonSpotz

Let me provide you some insights here, @vonSpots!

Question 1

The config symbol stands for the input parameter of the Function . You can name it whatever you like. Note the type of the configuration method, which expects a Function<Configuration, TokenStore> . The first generic in there describes the input parameter of the Function , thus a Configuration instance. The second generic describes the return value of the Function , which should be a TokenStore instance.

By using Java's lambda notation of [input] -> [output], ending up with something called config seems feasible given the input type. The component in charge of providing that config instance, is the framework itself.

You can see this within Axon Framework's configuration module . Lastly, it's worthwhile to note that Axon Framework does not necessitate the use of Spring at all. So, setting the config instance is not originating from Spring.

Question 2

In the provided sample, there's no connection between the input and the output. However, Axon Framework defaults to providing the entire Configuration object so that the user is able to retrieve Axon components from it to construct other infrastructure components.

An example of where this would be useful with the JpaTokenStore , is when you need to set the Serializer . Axon Framework will set the Serializer up within the Configuration . Hence, you can retrieve it from Axon's configuration to construct your component.

Question 3

Because Axon Framework does its own wiring of all components. You can integrate it with Spring if you like, but it does not rely on it at all. Thus, in the face of a "pure" Java configuration, you need to have some collecting component, the Configuration , to retrieve everything from. You could almost see it as the Application Context from Spring.

Furthermore, Axon Framework chooses to have users register lambdas instead of concrete objects to ensure components are constructed and wired in the right order.

Axon Framework has many moving components, with objects like the CommandBus , EventProcessors , TokenStores , and DeadlineManager`, not forgetting to mention the Message Handling Components users wire into it themselves. By having end users provide a lambda, the framework can decide when to invoke the lambda.

This allows the framework to ensure all required components are in place before a, in your sample, TrackingEventProcessor can utilize the TokenStore .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM