Add flag for disabling component scan
This commit is contained in:
committed by
Oleg Zhurakousky
parent
307292b959
commit
b4f5c0339f
@@ -78,11 +78,8 @@ import org.springframework.messaging.converter.StringMessageConverter;
|
||||
* @author Artem Bilan
|
||||
* @author Anshul Mehra
|
||||
*/
|
||||
@Configuration
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnMissingBean(FunctionCatalog.class)
|
||||
@ComponentScan(basePackages = "${spring.cloud.function.scan.packages:functions}", //
|
||||
includeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {
|
||||
Supplier.class, Function.class, Consumer.class }))
|
||||
public class ContextFunctionCatalogAutoConfiguration {
|
||||
|
||||
static final String PREFERRED_MAPPER_PROPERTY = "spring.http.converters.preferred-json-mapper";
|
||||
@@ -103,9 +100,18 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
return new RoutingFunction(functionCatalog, functionInspector, messageConverter);
|
||||
}
|
||||
|
||||
protected static class BeanFactoryFunctionCatalog
|
||||
extends AbstractComposableFunctionRegistry
|
||||
implements SmartInitializingSingleton, BeanFactoryAware {
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ComponentScan(basePackages = "${spring.cloud.function.scan.packages:functions}", //
|
||||
includeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE,
|
||||
classes = { Supplier.class, Function.class, Consumer.class }))
|
||||
@ConditionalOnProperty(prefix = "spring.cloud.function.scan", name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
protected static class PlainFunctionScanConfiguration {
|
||||
|
||||
}
|
||||
|
||||
protected static class BeanFactoryFunctionCatalog extends AbstractComposableFunctionRegistry
|
||||
implements SmartInitializingSingleton, BeanFactoryAware {
|
||||
|
||||
private ApplicationEventPublisher applicationEventPublisher;
|
||||
|
||||
@@ -118,16 +124,12 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public void afterSingletonsInstantiated() {
|
||||
Map<String, Supplier> supplierBeans = this.beanFactory
|
||||
.getBeansOfType(Supplier.class);
|
||||
Map<String, Function> functionBeans = this.beanFactory
|
||||
.getBeansOfType(Function.class);
|
||||
Map<String, Consumer> consumerBeans = this.beanFactory
|
||||
.getBeansOfType(Consumer.class);
|
||||
Map<String, Supplier> supplierBeans = this.beanFactory.getBeansOfType(Supplier.class);
|
||||
Map<String, Function> functionBeans = this.beanFactory.getBeansOfType(Function.class);
|
||||
Map<String, Consumer> consumerBeans = this.beanFactory.getBeansOfType(Consumer.class);
|
||||
Map<String, FunctionRegistration> functionRegistrationBeans = this.beanFactory
|
||||
.getBeansOfType(FunctionRegistration.class);
|
||||
this.doMerge(functionRegistrationBeans, consumerBeans, supplierBeans,
|
||||
functionBeans);
|
||||
.getBeansOfType(FunctionRegistration.class);
|
||||
this.doMerge(functionRegistrationBeans, consumerBeans, supplierBeans, functionBeans);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -139,14 +141,12 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
public void close() {
|
||||
if (this.applicationEventPublisher != null) {
|
||||
if (this.hasFunctions()) {
|
||||
this.applicationEventPublisher
|
||||
.publishEvent(new FunctionUnregistrationEvent(this,
|
||||
Function.class, this.getFunctionNames()));
|
||||
this.applicationEventPublisher.publishEvent(
|
||||
new FunctionUnregistrationEvent(this, Function.class, this.getFunctionNames()));
|
||||
}
|
||||
if (this.hasSuppliers()) {
|
||||
this.applicationEventPublisher
|
||||
.publishEvent(new FunctionUnregistrationEvent(this,
|
||||
Supplier.class, this.getSupplierNames()));
|
||||
this.applicationEventPublisher.publishEvent(
|
||||
new FunctionUnregistrationEvent(this, Supplier.class, this.getSupplierNames()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,8 +155,7 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
protected FunctionType findType(FunctionRegistration<?> functionRegistration, String name) {
|
||||
FunctionType functionType = super.findType(functionRegistration, name);
|
||||
if (functionType == null) {
|
||||
functionType = functionByNameExist(name)
|
||||
? new FunctionType(functionRegistration.getTarget().getClass())
|
||||
functionType = functionByNameExist(name) ? new FunctionType(functionRegistration.getTarget().getClass())
|
||||
: this.findType(name);
|
||||
}
|
||||
|
||||
@@ -179,9 +178,8 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("rawtypes")
|
||||
Set<FunctionRegistration<?>> merge(Map<String, FunctionRegistration> initial,
|
||||
Map<String, Consumer> consumers, Map<String, Supplier> suppliers,
|
||||
Map<String, Function> functions) {
|
||||
Set<FunctionRegistration<?>> merge(Map<String, FunctionRegistration> initial, Map<String, Consumer> consumers,
|
||||
Map<String, Supplier> suppliers, Map<String, Function> functions) {
|
||||
this.doMerge(initial, consumers, suppliers, functions);
|
||||
return null;
|
||||
}
|
||||
@@ -198,14 +196,13 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
}
|
||||
|
||||
private String getQualifier(String key) {
|
||||
if (this.beanFactory != null
|
||||
&& this.beanFactory.containsBeanDefinition(key)) {
|
||||
if (this.beanFactory != null && this.beanFactory.containsBeanDefinition(key)) {
|
||||
BeanDefinition beanDefinition = this.beanFactory.getBeanDefinition(key);
|
||||
Object source = beanDefinition.getSource();
|
||||
if (source instanceof StandardMethodMetadata) {
|
||||
StandardMethodMetadata metadata = (StandardMethodMetadata) source;
|
||||
Qualifier qualifier = AnnotatedElementUtils.findMergedAnnotation(
|
||||
metadata.getIntrospectedMethod(), Qualifier.class);
|
||||
Qualifier qualifier = AnnotatedElementUtils.findMergedAnnotation(metadata.getIntrospectedMethod(),
|
||||
Qualifier.class);
|
||||
if (qualifier != null && qualifier.value().length() > 0) {
|
||||
return qualifier.value();
|
||||
}
|
||||
@@ -215,8 +212,7 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
}
|
||||
|
||||
private boolean functionByNameExist(String name) {
|
||||
return name == null || this.beanFactory == null
|
||||
|| !this.beanFactory.containsBeanDefinition(name);
|
||||
return name == null || this.beanFactory == null || !this.beanFactory.containsBeanDefinition(name);
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@@ -236,21 +232,20 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
targets.put(registration.getTarget(), key);
|
||||
}
|
||||
|
||||
Stream.concat(consumerBeans.entrySet().stream(), Stream.concat(
|
||||
supplierBeans.entrySet().stream(), functionBeans.entrySet().stream()))
|
||||
Stream.concat(consumerBeans.entrySet().stream(),
|
||||
Stream.concat(supplierBeans.entrySet().stream(), functionBeans.entrySet().stream()))
|
||||
.forEach(entry -> {
|
||||
if (!targets.containsKey(entry.getValue())) {
|
||||
FunctionRegistration<Object> target = new FunctionRegistration<Object>(
|
||||
entry.getValue(),
|
||||
FunctionRegistration<Object> target = new FunctionRegistration<Object>(entry.getValue(),
|
||||
getAliases(entry.getKey()).toArray(new String[] {}));
|
||||
targets.put(target.getTarget(), entry.getKey());
|
||||
registrations.add(target);
|
||||
}
|
||||
});
|
||||
|
||||
registrations.forEach(registration -> register(registration,
|
||||
targets.get(registration.getTarget())));
|
||||
registrations.forEach(registration -> register(registration, targets.get(registration.getTarget())));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class PreferGsonOrMissingJacksonCondition extends AnyNestedCondition {
|
||||
@@ -271,7 +266,7 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(Gson.class)
|
||||
@ConditionalOnBean(Gson.class)
|
||||
@Conditional(PreferGsonOrMissingJacksonCondition.class)
|
||||
@@ -284,7 +279,7 @@ public class ContextFunctionCatalogAutoConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(ObjectMapper.class)
|
||||
@ConditionalOnBean(ObjectMapper.class)
|
||||
@ConditionalOnProperty(name = ContextFunctionCatalogAutoConfiguration.PREFERRED_MAPPER_PROPERTY, //
|
||||
|
||||
@@ -55,8 +55,7 @@ import org.springframework.util.ClassUtils;
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class ContextFunctionCatalogInitializer
|
||||
implements ApplicationContextInitializer<GenericApplicationContext> {
|
||||
public class ContextFunctionCatalogInitializer implements ApplicationContextInitializer<GenericApplicationContext> {
|
||||
|
||||
/**
|
||||
* Property name for ignoring pre initilizer.
|
||||
@@ -70,32 +69,27 @@ public class ContextFunctionCatalogInitializer
|
||||
|
||||
@Override
|
||||
public void initialize(GenericApplicationContext applicationContext) {
|
||||
if (enabled && applicationContext.getEnvironment()
|
||||
.getProperty("spring.functional.enabled", Boolean.class, false)) {
|
||||
ContextFunctionCatalogBeanRegistrar registrar = new ContextFunctionCatalogBeanRegistrar(
|
||||
applicationContext);
|
||||
if (enabled
|
||||
&& applicationContext.getEnvironment().getProperty("spring.functional.enabled", Boolean.class, false)) {
|
||||
ContextFunctionCatalogBeanRegistrar registrar = new ContextFunctionCatalogBeanRegistrar(applicationContext);
|
||||
applicationContext.addBeanFactoryPostProcessor(registrar);
|
||||
}
|
||||
}
|
||||
|
||||
static class ContextFunctionCatalogBeanRegistrar
|
||||
implements BeanDefinitionRegistryPostProcessor {
|
||||
static class ContextFunctionCatalogBeanRegistrar implements BeanDefinitionRegistryPostProcessor {
|
||||
|
||||
private GenericApplicationContext context;
|
||||
|
||||
ContextFunctionCatalogBeanRegistrar(
|
||||
GenericApplicationContext applicationContext) {
|
||||
ContextFunctionCatalogBeanRegistrar(GenericApplicationContext applicationContext) {
|
||||
this.context = applicationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
|
||||
throws BeansException {
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
|
||||
throws BeansException {
|
||||
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
|
||||
try {
|
||||
register(registry, this.context.getDefaultListableBeanFactory());
|
||||
}
|
||||
@@ -110,52 +104,41 @@ public class ContextFunctionCatalogInitializer
|
||||
}
|
||||
}
|
||||
|
||||
protected void register(BeanDefinitionRegistry registry,
|
||||
ConfigurableListableBeanFactory factory) throws Exception {
|
||||
protected void register(BeanDefinitionRegistry registry, ConfigurableListableBeanFactory factory)
|
||||
throws Exception {
|
||||
|
||||
performPreinitialization();
|
||||
|
||||
if (this.context.getBeanFactory().getBeanNamesForType(
|
||||
PropertySourcesPlaceholderConfigurer.class, false,
|
||||
if (this.context.getBeanFactory().getBeanNamesForType(PropertySourcesPlaceholderConfigurer.class, false,
|
||||
false).length == 0) {
|
||||
this.context.registerBean(PropertySourcesPlaceholderConfigurer.class,
|
||||
() -> PropertyPlaceholderAutoConfiguration
|
||||
.propertySourcesPlaceholderConfigurer());
|
||||
() -> PropertyPlaceholderAutoConfiguration.propertySourcesPlaceholderConfigurer());
|
||||
}
|
||||
|
||||
if (!this.context.getBeanFactory().containsBean(
|
||||
AnnotationConfigUtils.CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
|
||||
if (!this.context.getBeanFactory()
|
||||
.containsBean(AnnotationConfigUtils.CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
|
||||
// Switch off the ConfigurationClassPostProcessor
|
||||
this.context.registerBean(
|
||||
AnnotationConfigUtils.CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME,
|
||||
this.context.registerBean(AnnotationConfigUtils.CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME,
|
||||
DummyProcessor.class, () -> new DummyProcessor());
|
||||
// But switch on other annotation processing
|
||||
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.context);
|
||||
}
|
||||
if (!this.context.getBeanFactory().containsBean(
|
||||
ConfigurationPropertiesBindingPostProcessor.BEAN_NAME)) {
|
||||
new ConfigurationPropertiesBindingPostProcessorRegistrar()
|
||||
.registerBeanDefinitions(null, context);
|
||||
if (!this.context.getBeanFactory().containsBean(ConfigurationPropertiesBindingPostProcessor.BEAN_NAME)) {
|
||||
new ConfigurationPropertiesBindingPostProcessorRegistrar().registerBeanDefinitions(null, this.context);
|
||||
}
|
||||
|
||||
if (ClassUtils.isPresent("com.google.gson.Gson", null)
|
||||
&& "gson".equals(this.context.getEnvironment().getProperty(
|
||||
ContextFunctionCatalogAutoConfiguration.PREFERRED_MAPPER_PROPERTY,
|
||||
"gson"))) {
|
||||
if (this.context.getBeanFactory().getBeanNamesForType(Gson.class, false,
|
||||
false).length == 0) {
|
||||
if (ClassUtils.isPresent("com.google.gson.Gson", null) && "gson".equals(this.context.getEnvironment()
|
||||
.getProperty(ContextFunctionCatalogAutoConfiguration.PREFERRED_MAPPER_PROPERTY, "gson"))) {
|
||||
if (this.context.getBeanFactory().getBeanNamesForType(Gson.class, false, false).length == 0) {
|
||||
this.context.registerBean(Gson.class, () -> new Gson());
|
||||
}
|
||||
this.context.registerBean(JsonMapper.class,
|
||||
() -> new ContextFunctionCatalogAutoConfiguration.GsonConfiguration()
|
||||
.jsonMapper(this.context.getBean(Gson.class)));
|
||||
}
|
||||
else if (ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper",
|
||||
null)) {
|
||||
if (this.context.getBeanFactory().getBeanNamesForType(ObjectMapper.class,
|
||||
false, false).length == 0) {
|
||||
this.context.registerBean(ObjectMapper.class,
|
||||
() -> new ObjectMapper());
|
||||
else if (ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", null)) {
|
||||
if (this.context.getBeanFactory().getBeanNamesForType(ObjectMapper.class, false, false).length == 0) {
|
||||
this.context.registerBean(ObjectMapper.class, () -> new ObjectMapper());
|
||||
}
|
||||
this.context.registerBean(JsonMapper.class,
|
||||
() -> new ContextFunctionCatalogAutoConfiguration.JacksonConfiguration()
|
||||
@@ -163,35 +146,29 @@ public class ContextFunctionCatalogInitializer
|
||||
|
||||
}
|
||||
|
||||
String basePackage = this.context.getEnvironment()
|
||||
.getProperty("spring.cloud.function.scan.packages", "functions");
|
||||
if (new ClassPathResource(basePackage.replace(".", "/")).exists()) {
|
||||
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(
|
||||
this.context, false, this.context.getEnvironment(), this.context);
|
||||
String basePackage = this.context.getEnvironment().getProperty("spring.cloud.function.scan.packages",
|
||||
"functions");
|
||||
if (this.context.getEnvironment().getProperty("spring.cloud.function.scan.enabled", Boolean.class, true)
|
||||
&& new ClassPathResource(basePackage.replace(".", "/")).exists()) {
|
||||
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.context, false,
|
||||
this.context.getEnvironment(), this.context);
|
||||
scanner.addIncludeFilter(new AssignableTypeFilter(Function.class));
|
||||
scanner.addIncludeFilter(new AssignableTypeFilter(Supplier.class));
|
||||
scanner.addIncludeFilter(new AssignableTypeFilter(Consumer.class));
|
||||
for (BeanDefinition bean : scanner.findCandidateComponents(basePackage)) {
|
||||
String name = bean.getBeanClassName();
|
||||
Class<?> type = ClassUtils.resolveClassName(name,
|
||||
this.context.getClassLoader());
|
||||
Class<?> type = ClassUtils.resolveClassName(name, this.context.getClassLoader());
|
||||
this.context.registerBeanDefinition(name, bean);
|
||||
this.context.registerBean("registration_" + name,
|
||||
FunctionRegistration.class,
|
||||
() -> new FunctionRegistration<>(this.context.getBean(name),
|
||||
name).type(type));
|
||||
this.context.registerBean("registration_" + name, FunctionRegistration.class,
|
||||
() -> new FunctionRegistration<>(this.context.getBean(name), name).type(type));
|
||||
}
|
||||
}
|
||||
|
||||
if (this.context.getBeanFactory().getBeanNamesForType(FunctionCatalog.class,
|
||||
false, false).length == 0) {
|
||||
this.context.registerBean(InMemoryFunctionCatalog.class,
|
||||
() -> new InMemoryFunctionCatalog());
|
||||
this.context
|
||||
.registerBean(FunctionRegistrationPostProcessor.class,
|
||||
() -> new FunctionRegistrationPostProcessor(this.context
|
||||
.getAutowireCapableBeanFactory()
|
||||
.getBeanProvider(FunctionRegistration.class)));
|
||||
if (this.context.getBeanFactory().getBeanNamesForType(FunctionCatalog.class, false, false).length == 0) {
|
||||
this.context.registerBean(InMemoryFunctionCatalog.class, () -> new InMemoryFunctionCatalog());
|
||||
this.context.registerBean(FunctionRegistrationPostProcessor.class,
|
||||
() -> new FunctionRegistrationPostProcessor(this.context.getAutowireCapableBeanFactory()
|
||||
.getBeanProvider(FunctionRegistration.class)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,8 +211,7 @@ public class ContextFunctionCatalogInitializer
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName)
|
||||
throws BeansException {
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
if (bean instanceof FunctionRegistry) {
|
||||
FunctionRegistry catalog = (FunctionRegistry) bean;
|
||||
for (FunctionRegistration<?> registration : this.functions) {
|
||||
@@ -243,8 +219,7 @@ public class ContextFunctionCatalogInitializer
|
||||
"FunctionRegistration must define at least one name. Was empty");
|
||||
if (registration.getType() == null) {
|
||||
throw new IllegalStateException(
|
||||
"You need an explicit type for the function: "
|
||||
+ registration.getNames());
|
||||
"You need an explicit type for the function: " + registration.getNames());
|
||||
// TODO: in principle Spring could know how to extract this
|
||||
// from the supplier, but in practice there is no functional
|
||||
// bean registration with parametric types.
|
||||
|
||||
Reference in New Issue
Block a user