Flux.from() is cheap and can be used to marshal the inputs everywhere
internally. With this change users ought to be able to register any
function of any Publisher type.
Using this strategy libraries could be developed for supporting
Flux-like libraries (e.g. kstreams) that are not actually
reactive streams implementations.
If an isolated function doesn't have Message in its classpath, we
will never actually need to instantiate that class. This change
makes sure we check first.
This results in a better experience for users because the consumer
that they write is only applied to a Flux that is subscribed to
by the framework once. It gives better control over the flow of
foos, e.g. if some component wants to subscribe on a thread.
Avoids instantiating beans if not necessary, and allows user to
provide Function as a @SpringBootApplication (for instance), or
more generally as a source to the application context (as opposed
to being component scanned).
When a Supplier<Flux<Foo>> is composed with a Function<Foo,Bar>
the resulting handler (supplier) should have Flux as its output
wrapper still (the most general output wrapper type in the chain).
Since a function is wrapper in a FluxWrapper (and possibly also
an Isolated), the link is lost between the bean and the type
metadata without this change.
Makes it possible to support other "function" types in the future.
The user is always taking a risk with the lookup that the object
returned has the generic type desired (but that hasn't changed
with this commit). FunctionCatalog is a lot simpler as a result
and also a lot more flexible.
The web module doesn't really need to depend on tomcat and all of
the Spring Boot web stack, but users need a way to grab that stuff
quickly if they want it (hence the new starter).
Also removed all spring-boot-starter dependencies from core and
context modules.
Functions with Flux and Message (as well as POJOs and Flux of POJO
which were already supported) should now work if they are created in
an isolated class loader. Preconditions:
* The class loaders must have the reactor-core (and reactive-streams)
shared between the app and the function. Practically speaking this means
there has to be a parent class loader with just reactive types, and
sibling children for the app and the function. This is not a new
requirement (it was needed for Flux of POJO anyway).
* Message types are handled reflectively, so they don't have to be in a
shared class loader. But they do have to be on the class path on
both sides (obviously).
Fixes: gh-118
When the `BeanDefinition` for `Function` is a `FactoryBean`
(e.g. `GatewayProxyFactoryBean` in Spring Integration) and that
`BeanDefinition` isn't registered as `@Bean` method (e.g.
Spring Integration Java DSL parser), the `ContextFunctionCatalogAutoConfiguration`
doesn't resolve the target `Function` type properly
* Get the target `Function` bean type via `BeanFactory.getType(String)`
* Make fallback to the `Object.class` instead of bean type since we are
expecting here a generic type anyway