From 54deae5dbaa1969b7646e4d123faa7f03416f945 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 23 Oct 2018 13:45:36 +0100 Subject: [PATCH] Ensure FunctionalSpringApplication works with String sources --- .../context/FunctionalSpringApplication.java | 57 ++++++++++-------- .../string/FunctionalStringSourceTests.java | 59 +++++++++++++++++++ 2 files changed, 93 insertions(+), 23 deletions(-) create mode 100644 spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/string/FunctionalStringSourceTests.java diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionalSpringApplication.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionalSpringApplication.java index cc9dae1e7..7ebba189a 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionalSpringApplication.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionalSpringApplication.java @@ -54,6 +54,10 @@ public class FunctionalSpringApplication */ public static final String SPRING_WEB_APPLICATION_TYPE = "spring.main.web-application-type"; + public static void main(String[] args) throws Exception { + FunctionalSpringApplication.run(new Class[0], args); + } + public static ConfigurableApplicationContext run(Class primarySource, String... args) { return run(new Class[] { primarySource }, args); @@ -70,7 +74,8 @@ public class FunctionalSpringApplication if (ClassUtils.isPresent("org.springframework.web.reactive.DispatcherHandler", null)) { setWebApplicationType(WebApplicationType.REACTIVE); - } else { + } + else { setWebApplicationType(WebApplicationType.NONE); } } @@ -82,40 +87,39 @@ public class FunctionalSpringApplication if (context instanceof GenericApplicationContext) { GenericApplicationContext generic = (GenericApplicationContext) context; for (Object source : getAllSources()) { - if (source instanceof Class) { - Class type = (Class) source; - if (ApplicationContextInitializer.class.isAssignableFrom(type)) { - @SuppressWarnings("unchecked") - ApplicationContextInitializer initializer = BeanUtils - .instantiateClass(type, - ApplicationContextInitializer.class); - initializer.initialize(generic); - functional = true; - } - else if (Function.class.isAssignableFrom(type) - || Consumer.class.isAssignableFrom(type) - || Supplier.class.isAssignableFrom(type)) { - generic.registerBean("function", FunctionRegistration.class, - () -> new FunctionRegistration<>(context - .getAutowireCapableBeanFactory().createBean(type)) - .type(FunctionType.of(type))); - functional = true; + Class type = null; + Object handler = null; + if (source instanceof String) { + String name = (String) source; + if (ClassUtils.isPresent(name, null)) { + type = ClassUtils.resolveClassName(name, null); } } + else if (source instanceof Class) { + type = (Class) source; + } else { - Class type = source.getClass(); + type = source.getClass(); + handler = source; + } + if (type != null) { if (ApplicationContextInitializer.class.isAssignableFrom(type)) { + if (handler == null) { + handler = BeanUtils.instantiateClass(type); + } @SuppressWarnings("unchecked") - ApplicationContextInitializer initializer = (ApplicationContextInitializer) source; + ApplicationContextInitializer initializer = (ApplicationContextInitializer) handler; initializer.initialize(generic); functional = true; } else if (Function.class.isAssignableFrom(type) || Consumer.class.isAssignableFrom(type) || Supplier.class.isAssignableFrom(type)) { + Class functionType = type; + Object function = handler; generic.registerBean("function", FunctionRegistration.class, - () -> new FunctionRegistration<>(source) - .type(FunctionType.of(type))); + () -> new FunctionRegistration<>(handler(generic, function, functionType)) + .type(FunctionType.of(functionType))); functional = true; } } @@ -126,6 +130,13 @@ public class FunctionalSpringApplication } } + private Object handler(GenericApplicationContext generic, Object handler, Class type) { + if (handler == null) { + handler = generic.getAutowireCapableBeanFactory().createBean(type); + } + return handler; + } + @Override protected void load(ApplicationContext context, Object[] sources) { if (!context.getEnvironment().getProperty(SPRING_FUNCTIONAL_ENABLED, diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/string/FunctionalStringSourceTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/string/FunctionalStringSourceTests.java new file mode 100644 index 000000000..d606b8de3 --- /dev/null +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/string/FunctionalStringSourceTests.java @@ -0,0 +1,59 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.function.context.string; + +import java.util.function.Function; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.function.context.FunctionCatalog; +import org.springframework.cloud.function.context.test.FunctionalSpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +import reactor.core.publisher.Flux; + +/** + * Test that spring.main.sources works with the functional approach. + * + * @author Dave Syer + * + */ +@RunWith(SpringRunner.class) +@FunctionalSpringBootTest(classes = Object.class, properties = "spring.main.sources=org.springframework.cloud.function.context.string.FunctionalStringSourceTests.TestConfiguration") +public class FunctionalStringSourceTests { + + @Autowired + private FunctionCatalog catalog; + + @Test + public void words() throws Exception { + Function, Flux> function = catalog.lookup(Function.class, + "function"); + assertThat(function.apply(Flux.just("foo")).blockFirst()).isEqualTo("FOO"); + } + + protected static class TestConfiguration implements Function { + @Override + public String apply(String value) { + return value.toUpperCase(); + } + } +}