GH-514 Remove 'proxyInvokerIfNecessary()' method

It is really not needed as it does not add much value other then allows user to cast POJO function to its actual type. The reality is that the actual goald of POJO function is to make sure they can be looked at as plain Functions.

Resolves #514
This commit is contained in:
Oleg Zhurakousky
2020-05-26 15:42:31 +02:00
parent 79becb3f6b
commit ce28ce2cb6
4 changed files with 9 additions and 54 deletions

View File

@@ -216,7 +216,7 @@ public class BeanFactoryAwareFunctionRegistry extends SimpleFunctionRegistry imp
}
@Override
Type discovereFunctionTypeByName(String name) {
Type discoverFunctionTypeByName(String name) {
return FunctionContextUtils.findType(applicationContext.getBeanFactory(), name);
}

View File

@@ -48,7 +48,6 @@ import reactor.core.publisher.Mono;
import reactor.util.function.Tuples;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.cloud.function.context.FunctionProperties;
import org.springframework.cloud.function.context.FunctionRegistration;
@@ -89,7 +88,7 @@ import org.springframework.util.StringUtils;
*/
public class SimpleFunctionRegistry implements FunctionRegistry, FunctionInspector {
Log logger = LogFactory.getLog(BeanFactoryAwareFunctionRegistry.class);
Log logger = LogFactory.getLog(SimpleFunctionRegistry.class);
/**
* Identifies MessageConversionExceptions that happen when input can't be converted.
@@ -167,8 +166,7 @@ public class SimpleFunctionRegistry implements FunctionRegistry, FunctionInspect
}
}
Object function = this
.proxyInvokerIfNecessary((FunctionInvocationWrapper) this.compose(null, definition, acceptedOutputTypes));
FunctionInvocationWrapper function = (FunctionInvocationWrapper) this.compose(null, definition, acceptedOutputTypes);
return (T) function;
}
@@ -254,7 +252,7 @@ public class SimpleFunctionRegistry implements FunctionRegistry, FunctionInspect
return originalDefinition;
}
Type discovereFunctionTypeByName(String name) {
Type discoverFunctionTypeByName(String name) {
return this.registrationsByName.get(name).getType().getType();
}
@@ -289,7 +287,7 @@ public class SimpleFunctionRegistry implements FunctionRegistry, FunctionInspect
return null;
}
else {
Type functionType = this.discovereFunctionTypeByName(name);
Type functionType = this.discoverFunctionTypeByName(name);
if (functionType != null && functionType.toString().contains("org.apache.kafka.streams.")) {
logger
.debug("Kafka Streams function '" + definition + "' is not supported by spring-cloud-function.");
@@ -358,47 +356,6 @@ public class SimpleFunctionRegistry implements FunctionRegistry, FunctionInspect
&& !function.getClass().getPackage().getName().startsWith("org.springframework.cloud.function.compiler");
}
/*
* == OUTER PROXY ===
* For cases where function is POJO we need to be able to look it up as Function
* as well as the type of actual pojo (e.g., MyFunction f1 = catalog.lookup("myFunction");)
* To do this we wrap the target into CglibProxy (for cases when function is a POJO ) with the
* actual target class (e.g., MyFunction). Meanwhile the invocation will be delegated to
* the FunctionInvocationWrapper which will trigger the INNER PROXY. This effectively ensures that
* conversion, composition and/or fluxification would happen (code inside of FunctionInvocationWrapper)
* while the inner proxy invocation will delegate the invocation with already converted arguments
* to the actual target class (e.g., MyFunction).
*/
private Object proxyInvokerIfNecessary(FunctionInvocationWrapper functionInvoker) {
if (functionInvoker != null && AopUtils.isCglibProxy(functionInvoker.getTarget())) {
if (logger.isInfoEnabled()) {
logger
.info("Proxying POJO function: " + functionInvoker.functionDefinition + ". . ." + functionInvoker.target
.getClass());
}
ProxyFactory pf = new ProxyFactory(functionInvoker.getTarget());
pf.setProxyTargetClass(true);
pf.setInterfaces(Function.class, Supplier.class, Consumer.class);
pf.addAdvice(new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
// this will trigger the INNER PROXY
if (ObjectUtils.isEmpty(invocation.getArguments())) {
Object o = functionInvoker.get();
return o;
}
else {
// this is where we probably would need to gather all arguments into tuples
return functionInvoker.apply(invocation.getArguments()[0]);
}
}
});
return pf.getProxy();
}
return functionInvoker;
}
/*
* == INNER PROXY ===
* When dealing with POJO functions we still want to be able to treat them as any other

View File

@@ -16,8 +16,6 @@
package org.springframework.cloud.function.context.catalog;
import java.util.function.Function;
import org.junit.Test;
@@ -32,7 +30,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import static org.assertj.core.api.Assertions.assertThat;
/**
@@ -76,8 +73,8 @@ public class BeanFactoryAwarePojoFunctionRegistryTests {
public void testWithPojoFunction() {
FunctionCatalog catalog = this.configureCatalog();
MyFunctionLike f1 = catalog.lookup("myFunctionLike");
assertThat(f1.uppercase("foo")).isEqualTo("FOO");
// MyFunctionLike f1 = catalog.lookup("myFunctionLike");
// assertThat(f1.uppercase("foo")).isEqualTo("FOO");
Function<String, String> f2 = catalog.lookup("myFunctionLike");
assertThat(f2.apply("foo")).isEqualTo("FOO");
@@ -121,7 +118,6 @@ public class BeanFactoryAwarePojoFunctionRegistryTests {
public Function<String, String> func() {
return v -> v;
}
}
// POJO Function that implements Function