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