diff --git a/pom.xml b/pom.xml
index c614752b9..8409a5dd9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -100,10 +100,6 @@
org.apache.maven.plugins
maven-checkstyle-plugin
-
- io.spring.javaformat
- spring-javaformat-maven-plugin
-
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 0dd395aec..e15f6d861 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
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2019 the original author or authors.
+ * Copyright 2017-2019 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.
@@ -16,8 +16,6 @@
package org.springframework.cloud.function.context;
-import static java.util.Arrays.stream;
-
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -34,11 +32,16 @@ import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
+import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
+import org.springframework.util.ObjectUtils;
+
+import static java.util.Arrays.stream;
/**
* @author Dave Syer
- *
+ * @author Semyon Fishman
+ * @author Oleg Zhurakousky
*/
public class FunctionalSpringApplication
extends org.springframework.boot.SpringApplication {
@@ -84,62 +87,72 @@ public class FunctionalSpringApplication
return new FunctionalSpringApplication(primarySources).run(args);
}
+ @SuppressWarnings("unchecked")
@Override
protected void postProcessApplicationContext(ConfigurableApplicationContext context) {
super.postProcessApplicationContext(context);
boolean functional = false;
- if (context instanceof GenericApplicationContext) {
- GenericApplicationContext generic = (GenericApplicationContext) context;
- for (Object source : getAllSources()) {
- Class> type = null;
- Object handler = null;
- if (source instanceof String) {
- String name = (String) source;
- if (ClassUtils.isPresent(name, null)) {
- type = ClassUtils.resolveClassName(name, null);
- }
+ Assert.isInstanceOf(GenericApplicationContext.class, context,
+ "ApplicationContext must be an instanceof GenericApplicationContext");
+ for (Object source : getAllSources()) {
+ 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 if (source instanceof Class>) {
+ type = (Class>) source;
+ }
+ else {
+ type = source.getClass();
+ handler = source;
+ }
+ if (ApplicationContextInitializer.class.isAssignableFrom(type)) {
+ if (handler == null) {
+ handler = BeanUtils.instantiateClass(type);
+ }
+
+ ApplicationContextInitializer initializer =
+ (ApplicationContextInitializer) handler;
+ initializer.initialize(context);
+ functional = true;
+ }
+ else if (Function.class.isAssignableFrom(type)
+ || Consumer.class.isAssignableFrom(type)
+ || Supplier.class.isAssignableFrom(type)) {
+ Class> functionType = type;
+ Object function = handler;
+ if (source.equals(functionType)) {
+ context.addBeanFactoryPostProcessor(beanFactory -> {
+ BeanDefinitionRegistry bdRegistry = (BeanDefinitionRegistry) beanFactory;
+ if (!ObjectUtils.isEmpty(context.getBeanNamesForType(functionType))) {
+ stream(context.getBeanNamesForType(functionType))
+ .forEach(beanName -> bdRegistry.registerAlias(beanName, "function"));
+ }
+ else {
+ this.register((GenericApplicationContext) context, function, functionType);
+ }
+ });
}
else {
- type = source.getClass();
- handler = source;
+ this.register((GenericApplicationContext) context, function, functionType);
}
- if (type != null) {
- if (ApplicationContextInitializer.class.isAssignableFrom(type)) {
- if (handler == null) {
- handler = BeanUtils.instantiateClass(type);
- }
- @SuppressWarnings("unchecked")
- 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<>(
- handler(generic, function, functionType))
- .type(FunctionType.of(functionType)));
- if (source.equals(functionType)) {
- context.addBeanFactoryPostProcessor(beanFactory -> {
- BeanDefinitionRegistry bdRegistry = (BeanDefinitionRegistry) beanFactory;
- stream(beanFactory.getBeanNamesForType(functionType))
- .forEach(bdRegistry::removeBeanDefinition);
- });
- }
- functional = true;
- }
- }
- }
- if (functional) {
- defaultProperties(generic);
+ functional = true;
}
}
+ if (functional) {
+ defaultProperties(context);
+ }
+ }
+
+ private void register(GenericApplicationContext context, Object function, Class> functionType) {
+ context.registerBean("function", FunctionRegistration.class,
+ () -> new FunctionRegistration<>(
+ handler(context, function, functionType))
+ .type(FunctionType.of(functionType)));
}
private Object handler(GenericApplicationContext generic, Object handler,
diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/HybridFunctionalRegistrationTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/HybridFunctionalRegistrationTests.java
new file mode 100644
index 000000000..fd420a085
--- /dev/null
+++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/HybridFunctionalRegistrationTests.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2019-2019 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;
+
+import java.util.function.Function;
+
+import org.junit.Test;
+
+import org.springframework.boot.SpringBootConfiguration;
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
+import org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.Bean;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ *
+ * @author Oleg Zhurakousky
+ *
+ */
+public class HybridFunctionalRegistrationTests {
+
+ // see https://github.com/spring-cloud/spring-cloud-function/issues/258
+ @Test
+ public void testNoDoubleRegistrationInHybridMode() {
+ ConfigurableApplicationContext context = FunctionalSpringApplication
+ .run(UppercaseFunction.class, "--spring.functional.enabled=false");
+ assertThat(context.containsBean("function")).isTrue();
+ assertThat(context.getBeansOfType(UppercaseFunction.class).size()).isEqualTo(1);
+ }
+
+ @SpringBootConfiguration
+ @ImportAutoConfiguration({
+ ContextFunctionCatalogAutoConfiguration.class,
+ JacksonAutoConfiguration.class }
+ )
+ public static class UppercaseFunction implements Function {
+
+ @Override
+ public String apply(String t) {
+ System.out.println("Receoved " + t);
+ return t;
+ }
+
+ @Bean
+ public Function foo() {
+ return x -> x;
+ }
+ }
+
+}