GH-364 Additional cleanup and small refactoring for Kotlin lambda support
This commit is contained in:
@@ -50,6 +50,16 @@ import org.springframework.util.CollectionUtils;
|
||||
*/
|
||||
public class FunctionRegistration<T> implements BeanNameAware {
|
||||
|
||||
/**
|
||||
* Suffix used to add to the name of FunctionRegistration bean that
|
||||
* corresponds to the an actual function bean. It is often used when
|
||||
* the actual function bean may not be a java Function (e.g., Kotlin)
|
||||
* and certain custom wrapping is required.
|
||||
* <br>
|
||||
* NOTE: This is not intended as oublis API
|
||||
*/
|
||||
public static String REGISTRATION_NAME_SUFFIX = "_registration";
|
||||
|
||||
private final Set<String> names = new LinkedHashSet<>();
|
||||
|
||||
private final Map<String, String> properties = new LinkedHashMap<>();
|
||||
|
||||
@@ -177,24 +177,17 @@ public class BeanFactoryAwareFunctionRegistry
|
||||
function = this.registrationsByName.get(name);
|
||||
}
|
||||
|
||||
if (function != null && this.isKotlin(function.getClass())) {
|
||||
function = this.applicationContext.getBean("_" + name, FunctionRegistration.class);
|
||||
if (function != null && this.notFunction(function.getClass())
|
||||
&& this.applicationContext.containsBean(name + FunctionRegistration.REGISTRATION_NAME_SUFFIX)) { // e.g., Kotlin lambdas
|
||||
function = this.applicationContext.getBean(name + FunctionRegistration.REGISTRATION_NAME_SUFFIX, FunctionRegistration.class);
|
||||
}
|
||||
return function;
|
||||
}
|
||||
|
||||
private boolean isKotlin(Class<?> functionClass) {
|
||||
if (functionClass != null) {
|
||||
if ("kotlin.jvm.internal.Lambda".equals(functionClass.getName())) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return this.isKotlin(functionClass.getSuperclass());
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
private boolean notFunction(Class<?> functionClass) {
|
||||
return !Function.class.isAssignableFrom(functionClass)
|
||||
&& !Supplier.class.isAssignableFrom(functionClass)
|
||||
&& !Consumer.class.isAssignableFrom(functionClass);
|
||||
}
|
||||
|
||||
|
||||
@@ -204,8 +197,8 @@ public class BeanFactoryAwareFunctionRegistry
|
||||
beanDefinitionExists = this.applicationContext.getBeanFactory().containsBeanDefinition(names[i]);
|
||||
}
|
||||
if (!beanDefinitionExists) {
|
||||
logger.info("BeanDefinition for function name(s) `" + Arrays.asList(names) +
|
||||
"` can not be located. FunctionType will be based on " + function.getClass());
|
||||
logger.info("BeanDefinition for function name(s) '" + Arrays.asList(names) +
|
||||
"' can not be located. FunctionType will be based on " + function.getClass());
|
||||
}
|
||||
return beanDefinitionExists
|
||||
? FunctionType.of(FunctionContextUtils.findType(applicationContext.getBeanFactory(), names)).getType()
|
||||
@@ -216,11 +209,11 @@ public class BeanFactoryAwareFunctionRegistry
|
||||
if (StringUtils.isEmpty(definition)) {
|
||||
// the underscores are for Kotlin function registrations (see KotlinLambdaToFunctionAutoConfiguration)
|
||||
String[] functionNames = Stream.of(this.applicationContext.getBeanNamesForType(Function.class))
|
||||
.filter(n -> !n.startsWith("_") && !n.equals(RoutingFunction.FUNCTION_NAME)).toArray(String[]::new);
|
||||
.filter(n -> !n.endsWith(FunctionRegistration.REGISTRATION_NAME_SUFFIX) && !n.equals(RoutingFunction.FUNCTION_NAME)).toArray(String[]::new);
|
||||
String[] consumerNames = Stream.of(this.applicationContext.getBeanNamesForType(Consumer.class))
|
||||
.filter(n -> !n.startsWith("_") && !n.equals(RoutingFunction.FUNCTION_NAME)).toArray(String[]::new);
|
||||
.filter(n -> !n.endsWith(FunctionRegistration.REGISTRATION_NAME_SUFFIX) && !n.equals(RoutingFunction.FUNCTION_NAME)).toArray(String[]::new);
|
||||
String[] supplierNames = Stream.of(this.applicationContext.getBeanNamesForType(Supplier.class))
|
||||
.filter(n -> !n.startsWith("_") && !n.equals(RoutingFunction.FUNCTION_NAME)).toArray(String[]::new);
|
||||
.filter(n -> !n.endsWith(FunctionRegistration.REGISTRATION_NAME_SUFFIX) && !n.equals(RoutingFunction.FUNCTION_NAME)).toArray(String[]::new);
|
||||
/*
|
||||
* we may need to add BiFunction and BiConsumer at some point
|
||||
*/
|
||||
|
||||
@@ -57,7 +57,7 @@ import org.springframework.util.ObjectUtils;
|
||||
* @since 2.0
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass(name = "kotlin.jvm.functions.Function1")
|
||||
@ConditionalOnClass(name = "kotlin.jvm.functions.Function0")
|
||||
class KotlinLambdaToFunctionAutoConfiguration {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
@@ -88,7 +88,7 @@ class KotlinLambdaToFunctionAutoConfiguration {
|
||||
ConstructorArgumentValues ca = new ConstructorArgumentValues();
|
||||
ca.addGenericArgumentValue(beanDefinition);
|
||||
cbd.setConstructorArgumentValues(ca);
|
||||
((BeanDefinitionRegistry) beanFactory).registerBeanDefinition("_" + beanDefinitionName, cbd);
|
||||
((BeanDefinitionRegistry) beanFactory).registerBeanDefinition(beanDefinitionName + FunctionRegistration.REGISTRATION_NAME_SUFFIX, cbd);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,7 +164,10 @@ class KotlinLambdaToFunctionAutoConfiguration {
|
||||
|
||||
@Override
|
||||
public FunctionRegistration getObject() throws Exception {
|
||||
Type functionType = FunctionContextUtils.findType(this.name.substring(1), this.beanFactory);
|
||||
String name = this.name.endsWith(FunctionRegistration.REGISTRATION_NAME_SUFFIX)
|
||||
? this.name.replace(FunctionRegistration.REGISTRATION_NAME_SUFFIX, "")
|
||||
: this.name;
|
||||
Type functionType = FunctionContextUtils.findType(name, this.beanFactory);
|
||||
FunctionRegistration<?> registration = new FunctionRegistration<>(this, name);
|
||||
Type[] types = ((ParameterizedType) functionType).getActualTypeArguments();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user