GH-3047: Add GatewayProxySpec for Java DSL

Fixes https://github.com/spring-projects/spring-integration/issues/3047

* Improve `GatewayProxyFactoryBean` to determine the return type of the
method call from the interface generic types, when the `serviceInterface`
is a `java.util.function.Function`
* Propagate `MethodArgsHolder` as a `rootObject` for SpEL evaluations
* Deprecate `#gatewayMethod` and `#args` evaluation context variables
in favor of `MethodArgsHolder` as root object.
They will be removed in the future release and a single
`EvaluationContext` will be used for all the gateway expressions
* Introduce an
`IntegrationFlows.from(Class<?> serviceInterface, Consumer<GatewayProxySpec> endpointConfigurer)`
to allow to configure any valid gateway proxy options similar to what
we have with the `<gateway>` and `@MessagingGateway`.
This way we are very close to consistency between different approaches

* * Remove `default` prefix from `GatewayProxySpec` options
* Document the change
This commit is contained in:
Artem Bilan
2019-09-06 13:46:16 -04:00
committed by GitHub
parent c668a046e1
commit 29bebdba97
17 changed files with 565 additions and 132 deletions

View File

@@ -1171,7 +1171,10 @@ Nevertheless, the `requestChannel` is ignored and overridden with that internal
Otherwise, creating such a configuration by using `IntegrationFlow` does not make sense.
By default a `GatewayProxyFactoryBean` gets a conventional bean name, such as `[FLOW_BEAN_NAME.gateway]`.
You can change that ID by using the `@MessagingGateway.name()` attribute or the overloaded `from(Class<?> serviceInterface, String beanName)` factory method.
You can change that ID by using the `@MessagingGateway.name()` attribute or the overloaded `IntegrationFlows.from(Class<?> serviceInterface, Consumer<GatewayProxySpec> endpointConfigurer)` factory method.
Also all the attributes from the `@MessagingGateway` annotation on the interface are applied to the target `GatewayProxyFactoryBean`.
When annotation configuration is not applicable, the `Consumer<GatewayProxySpec>` variant can be used for providing appropriate option for the target proxy.
This DSL method is available starting with version 5.2; the method `IntegrationFlows.from(Class<?> serviceInterface, String beanName)` is deprecated in favor of `GatewayProxySpec.beanName()` option.
With Java 8, you can even create an integration gateway with the `java.util.function` interfaces, as the following example shows:
@@ -1180,7 +1183,7 @@ With Java 8, you can even create an integration gateway with the `java.util.func
----
@Bean
public IntegrationFlow errorRecovererFlow() {
return IntegrationFlows.from(Function.class, "errorRecovererFunction")
return IntegrationFlows.from(Function.class, (gateway) -> gateway.beanName("errorRecovererFunction"))
.handle((GenericHandler<?>) (p, h) -> {
throw new RuntimeException("intentional");
}, e -> e.advice(retryAdvice()))

View File

@@ -156,7 +156,9 @@ In the preceding example a different value is set for the 'RESPONSE_TYPE' header
The `<header/>` element supports `expression` as an alternative to `value`.
The SpEL expression is evaluated to determine the value of the header.
There is no `#root` object, but the following variables are available:
Starting with version 5.2, the `#root` object of the evaluation context is a `MethodArgsHolder` with `getMethod()` and `getArgs()` accessors.
These two expression evaluation context variables are deprecated since version 5.2:
* #args: An `Object[]` containing the method arguments
* #gatewayMethod: The object (derived from `java.reflect.Method`) that represents the method in the `service-interface` that was invoked.
@@ -164,8 +166,8 @@ A header containing this variable can be used later in the flow (for example, fo
For example, if you wish to route on the simple method name, you might add a header with the following expression: `#gatewayMethod.name`.
NOTE: The `java.reflect.Method` is not serializable.
A header with an expression of `#gatewayMethod` is lost if you later serialize the message.
Consequently, you may wish to use `#gatewayMethod.name` or `#gatewayMethod.toString()` in those cases.
A header with an expression of `method` is lost if you later serialize the message.
Consequently, you may wish to use `method.name` or `method.toString()` in those cases.
The `toString()` method provides a `String` representation of the method, including parameter and return types.
Since version 3.0, `<default-header/>` elements can be defined to add headers to all the messages produced by the gateway, regardless of the method invoked.

View File

@@ -12,7 +12,7 @@ If you are interested in the changes and features that were introduced in earlie
If you are interested in more details, see the Issue Tracker tickets that were resolved as part of the 5.2 development process.
[[x5.2-package-clas]]
[[x5.2-package-class]]
=== Package and Class Changes
`Pausable` has been moved from `o.s.i.endpoint` to `o.s.i.core`.
@@ -86,6 +86,12 @@ See <<./aggregator.adoc#aggregator-api,Aggregator Programming Model>> for more i
All the `MessageHandlingException` s thrown in the framework, includes now a bean resource and source for back tracking a configuration part in case no end-user code involved.
See <<./error-handling.adoc#error-handling,Error Handling>> for more information.
For better end-user experience, Java DSL now provides a configurer variant for starting flow with a gateway interface.
See `IntegrationFlows.from(Class<?> serviceInterface, Consumer<GatewayProxySpec> endpointConfigurer)` JavaDocs for more information.
Also a `MethodArgsHolder` is now a root object for evaluation context for all the expressions in the `GatewayProxyFactoryBean`.
The `#args` and `#method` evaluation context variables are now deprecated.
See <<./gateway.adoc#gateway,Messaging Gateways>> for more information.
[[x5.2-amqp]]
==== AMQP Changes