Inspect bean class if it is available
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).
This commit is contained in:
@@ -99,7 +99,7 @@ public class FunctionType {
|
||||
|
||||
public static boolean isWrapper(Type type) {
|
||||
if (type instanceof ParameterizedType) {
|
||||
type = ((ParameterizedType)type).getRawType();
|
||||
type = ((ParameterizedType) type).getRawType();
|
||||
}
|
||||
return Publisher.class.equals(type) || Flux.class.equals(type)
|
||||
|| Mono.class.equals(type) || Optional.class.equals(type);
|
||||
@@ -222,13 +222,19 @@ public class FunctionType {
|
||||
private Class<?> findType(ParamType paramType) {
|
||||
int index = paramType.isOutput() ? 1 : 0;
|
||||
Type type = this.type;
|
||||
if (type instanceof Class) {
|
||||
for (Type iface : ((Class<?>) type).getGenericInterfaces()) {
|
||||
boolean found = false;
|
||||
while (!found && type instanceof Class && type != Object.class) {
|
||||
Class<?> clz = (Class<?>) type;
|
||||
for (Type iface : clz.getGenericInterfaces()) {
|
||||
if (iface.getTypeName().startsWith("java.util.function")) {
|
||||
type = iface;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
type = clz.getSuperclass();
|
||||
}
|
||||
}
|
||||
Type param = extractType(type, paramType, index);
|
||||
if (param != null) {
|
||||
|
||||
@@ -539,14 +539,22 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
param = new FunctionType(resolvable.getType());
|
||||
}
|
||||
else {
|
||||
Object bean = this.registry.getBean(name);
|
||||
if (bean instanceof FunctionFactoryMetadata) {
|
||||
FunctionFactoryMetadata<?> factory = (FunctionFactoryMetadata<?>) bean;
|
||||
Type type = factory.getFactoryMethod().getGenericReturnType();
|
||||
Class<?> beanClass = definition.getBeanClass();
|
||||
if (beanClass != null && !FunctionFactoryMetadata.class
|
||||
.isAssignableFrom(beanClass)) {
|
||||
Type type = beanClass;
|
||||
param = new FunctionType(type);
|
||||
}
|
||||
else {
|
||||
param = new FunctionType(bean.getClass());
|
||||
Object bean = this.registry.getBean(name);
|
||||
if (bean instanceof FunctionFactoryMetadata) {
|
||||
FunctionFactoryMetadata<?> factory = (FunctionFactoryMetadata<?>) bean;
|
||||
Type type = factory.getFactoryMethod().getGenericReturnType();
|
||||
param = new FunctionType(type);
|
||||
}
|
||||
else {
|
||||
param = new FunctionType(bean.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +123,20 @@ public class ContextFunctionCatalogAutoConfigurationTests {
|
||||
.isEqualTo(Foo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configurationFunction() {
|
||||
create(FunctionConfiguration.class);
|
||||
assertThat(context.getBean("foos")).isInstanceOf(Function.class);
|
||||
assertThat(catalog.<Function<?, ?>>lookup(Function.class, "foos"))
|
||||
.isInstanceOf(Function.class);
|
||||
assertThat(inspector.getInputType(catalog.lookup(Function.class, "foos")))
|
||||
.isEqualTo(String.class);
|
||||
assertThat(inspector.getOutputType(catalog.lookup(Function.class, "foos")))
|
||||
.isEqualTo(Foo.class);
|
||||
assertThat(inspector.getInputWrapper(catalog.lookup(Function.class, "foos")))
|
||||
.isEqualTo(Flux.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dependencyInjection() {
|
||||
create(DependencyInjectionConfiguration.class);
|
||||
@@ -558,6 +572,22 @@ public class ContextFunctionCatalogAutoConfigurationTests {
|
||||
}
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@Configuration("foos")
|
||||
protected static class FunctionConfiguration
|
||||
implements Function<Flux<String>, Flux<Foo>> {
|
||||
|
||||
@Override
|
||||
public Flux<Foo> apply(Flux<String> flux) {
|
||||
return flux.map(foo -> new Foo(value() + ": " + foo.toUpperCase()));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public String value() {
|
||||
return "Hello";
|
||||
}
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@Configuration
|
||||
@ComponentScan(basePackageClasses = FooConfiguration.class)
|
||||
|
||||
Reference in New Issue
Block a user