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 {
|
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 Set<String> names = new LinkedHashSet<>();
|
||||||
|
|
||||||
private final Map<String, String> properties = new LinkedHashMap<>();
|
private final Map<String, String> properties = new LinkedHashMap<>();
|
||||||
|
|||||||
@@ -177,24 +177,17 @@ public class BeanFactoryAwareFunctionRegistry
|
|||||||
function = this.registrationsByName.get(name);
|
function = this.registrationsByName.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (function != null && this.isKotlin(function.getClass())) {
|
if (function != null && this.notFunction(function.getClass())
|
||||||
function = this.applicationContext.getBean("_" + name, FunctionRegistration.class);
|
&& 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;
|
return function;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isKotlin(Class<?> functionClass) {
|
private boolean notFunction(Class<?> functionClass) {
|
||||||
if (functionClass != null) {
|
return !Function.class.isAssignableFrom(functionClass)
|
||||||
if ("kotlin.jvm.internal.Lambda".equals(functionClass.getName())) {
|
&& !Supplier.class.isAssignableFrom(functionClass)
|
||||||
return true;
|
&& !Consumer.class.isAssignableFrom(functionClass);
|
||||||
}
|
|
||||||
else {
|
|
||||||
return this.isKotlin(functionClass.getSuperclass());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -204,8 +197,8 @@ public class BeanFactoryAwareFunctionRegistry
|
|||||||
beanDefinitionExists = this.applicationContext.getBeanFactory().containsBeanDefinition(names[i]);
|
beanDefinitionExists = this.applicationContext.getBeanFactory().containsBeanDefinition(names[i]);
|
||||||
}
|
}
|
||||||
if (!beanDefinitionExists) {
|
if (!beanDefinitionExists) {
|
||||||
logger.info("BeanDefinition for function name(s) `" + Arrays.asList(names) +
|
logger.info("BeanDefinition for function name(s) '" + Arrays.asList(names) +
|
||||||
"` can not be located. FunctionType will be based on " + function.getClass());
|
"' can not be located. FunctionType will be based on " + function.getClass());
|
||||||
}
|
}
|
||||||
return beanDefinitionExists
|
return beanDefinitionExists
|
||||||
? FunctionType.of(FunctionContextUtils.findType(applicationContext.getBeanFactory(), names)).getType()
|
? FunctionType.of(FunctionContextUtils.findType(applicationContext.getBeanFactory(), names)).getType()
|
||||||
@@ -216,11 +209,11 @@ public class BeanFactoryAwareFunctionRegistry
|
|||||||
if (StringUtils.isEmpty(definition)) {
|
if (StringUtils.isEmpty(definition)) {
|
||||||
// the underscores are for Kotlin function registrations (see KotlinLambdaToFunctionAutoConfiguration)
|
// the underscores are for Kotlin function registrations (see KotlinLambdaToFunctionAutoConfiguration)
|
||||||
String[] functionNames = Stream.of(this.applicationContext.getBeanNamesForType(Function.class))
|
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))
|
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))
|
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
|
* we may need to add BiFunction and BiConsumer at some point
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ import org.springframework.util.ObjectUtils;
|
|||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConditionalOnClass(name = "kotlin.jvm.functions.Function1")
|
@ConditionalOnClass(name = "kotlin.jvm.functions.Function0")
|
||||||
class KotlinLambdaToFunctionAutoConfiguration {
|
class KotlinLambdaToFunctionAutoConfiguration {
|
||||||
|
|
||||||
protected final Log logger = LogFactory.getLog(getClass());
|
protected final Log logger = LogFactory.getLog(getClass());
|
||||||
@@ -88,7 +88,7 @@ class KotlinLambdaToFunctionAutoConfiguration {
|
|||||||
ConstructorArgumentValues ca = new ConstructorArgumentValues();
|
ConstructorArgumentValues ca = new ConstructorArgumentValues();
|
||||||
ca.addGenericArgumentValue(beanDefinition);
|
ca.addGenericArgumentValue(beanDefinition);
|
||||||
cbd.setConstructorArgumentValues(ca);
|
cbd.setConstructorArgumentValues(ca);
|
||||||
((BeanDefinitionRegistry) beanFactory).registerBeanDefinition("_" + beanDefinitionName, cbd);
|
((BeanDefinitionRegistry) beanFactory).registerBeanDefinition(beanDefinitionName + FunctionRegistration.REGISTRATION_NAME_SUFFIX, cbd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,7 +164,10 @@ class KotlinLambdaToFunctionAutoConfiguration {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FunctionRegistration getObject() throws Exception {
|
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);
|
FunctionRegistration<?> registration = new FunctionRegistration<>(this, name);
|
||||||
Type[] types = ((ParameterizedType) functionType).getActualTypeArguments();
|
Type[] types = ((ParameterizedType) functionType).getActualTypeArguments();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user