More cleanup and simplification in AbstractComposableFunctionRegistry

- We now rely on single map (no consumers, suppliers)
- Simplified FunctionCreatorConfiguration to map FunctionType between class loaders
This commit is contained in:
Oleg Zhurakousky
2019-04-03 21:04:40 +02:00
parent 085204bad2
commit 9a3181532c
3 changed files with 101 additions and 51 deletions

View File

@@ -16,6 +16,7 @@
package org.springframework.cloud.function.context;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
@@ -29,6 +30,7 @@ import reactor.core.publisher.Flux;
import org.springframework.core.ResolvableType;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.messaging.Message;
import org.springframework.util.ReflectionUtils;
/**
* @author Dave Syer
@@ -66,6 +68,37 @@ public class FunctionType {
this.message = messageType();
}
/*
* Experimental for now. Used (reflectively) in FunctionCreatorConfiguration to effectively
* map an existing FunctionType created by one class loader to another.
*/
@SuppressWarnings("unused") // it is used
private FunctionType(Object functionType) throws Exception {
Field field = ReflectionUtils.findField(functionType.getClass(), "type");
field.setAccessible(true);
this.type = (Type) field.get(functionType);
field = ReflectionUtils.findField(functionType.getClass(), "inputWrapper");
field.setAccessible(true);
this.inputWrapper = (Class<?>) field.get(functionType);
field = ReflectionUtils.findField(functionType.getClass(), "outputWrapper");
field.setAccessible(true);
this.outputWrapper = (Class<?>) field.get(functionType);
field = ReflectionUtils.findField(functionType.getClass(), "inputType");
field.setAccessible(true);
this.inputType = (Class<?>) field.get(functionType);
field = ReflectionUtils.findField(functionType.getClass(), "outputType");
field.setAccessible(true);
this.outputType = (Class<?>) field.get(functionType);
field = ReflectionUtils.findField(functionType.getClass(), "message");
field.setAccessible(true);
this.message = (boolean) field.get(functionType);
}
public static boolean isWrapper(Type type) {
if (type instanceof ParameterizedType) {
type = ((ParameterizedType) type).getRawType();

View File

@@ -67,8 +67,6 @@ import org.springframework.util.StringUtils;
public abstract class AbstractComposableFunctionRegistry implements FunctionRegistry,
FunctionInspector, ApplicationEventPublisherAware, EnvironmentAware {
private final Map<String, Object> suppliers = new ConcurrentHashMap<>();
private final Map<String, Object> functions = new ConcurrentHashMap<>();
private final Map<Object, String> names = new ConcurrentHashMap<>();
@@ -113,7 +111,10 @@ public abstract class AbstractComposableFunctionRegistry implements FunctionRegi
* @return immutable {@link Set} of available {@link Supplier} names.
*/
public Set<String> getSupplierNames() {
return this.suppliers.keySet();
return this.functions.entrySet().stream()
.filter(entry -> entry.getValue() instanceof Supplier)
.map(entry -> entry.getKey())
.collect(Collectors.toSet());
}
/**
@@ -121,7 +122,10 @@ public abstract class AbstractComposableFunctionRegistry implements FunctionRegi
* @return immutable {@link Set} of available {@link Function} names.
*/
public Set<String> getFunctionNames() {
return this.functions.keySet();
return this.functions.entrySet().stream()
.filter(entry -> !(entry.getValue() instanceof Supplier))
.map(entry -> entry.getKey())
.collect(Collectors.toSet());
}
public boolean hasSuppliers() {
@@ -140,7 +144,7 @@ public abstract class AbstractComposableFunctionRegistry implements FunctionRegi
*/
@Override
public int size() {
return getSupplierNames().size() + getFunctionNames().size();
return this.functions.size();
}
public FunctionType getFunctionType(String name) {
@@ -243,7 +247,7 @@ public abstract class AbstractComposableFunctionRegistry implements FunctionRegi
protected void addSupplier(String name, Supplier<?> supplier) {
this.suppliers.put(name, supplier);
this.functions.put(name, supplier);
}
protected void addFunction(String name, Function<?, ?> function) {
@@ -325,16 +329,16 @@ public abstract class AbstractComposableFunctionRegistry implements FunctionRegi
}
private FunctionRegistration<?> find(String name, boolean supplierFound) {
Object result = this.suppliers.get(name);
if (result == null) {
result = this.functions.get(name);
}
Object result = this.functions.get(name);
// if (result == null) {
// result = this.functions.get(name);
// }
if (result == null && !StringUtils.hasText(name)) {
if (supplierFound && this.functions.size() == 1) {
result = this.functions.values().iterator().next();
if (supplierFound && this.getFunctionNames().size() == 1) {
result = this.functions.get(this.getFunctionNames().iterator().next());
}
else if (!supplierFound && this.suppliers.size() == 1) {
result = this.suppliers.values().iterator().next();
else if (!supplierFound && this.getSupplierNames().size() == 1) {
result = this.functions.get(this.getSupplierNames().iterator().next());
}
}
@@ -426,24 +430,9 @@ public abstract class AbstractComposableFunctionRegistry implements FunctionRegi
}
private Object doLookup(Class<?> type, String name) {
Object function = null;
if (type == null) {
function = this.compose(name, this.functions);
if (function == null) {
function = this.compose(name, this.suppliers);
}
}
else if (Function.class.isAssignableFrom(type)) {
Object composed = this.compose(name, this.functions);
if (composed != null && Function.class.isAssignableFrom(composed.getClass())) {
function = composed;
}
}
else if (Supplier.class.isAssignableFrom(type)) {
Object composed = this.compose(name, this.suppliers);
if (composed != null && Supplier.class.isAssignableFrom(composed.getClass())) {
function = composed;
}
Object function = this.compose(name, this.functions);
if (function != null && type != null && !type.isAssignableFrom(function.getClass())) {
function = null;
}
return function;
}