Support registration of non-public BeanDefinitionReader via @ImportResource
Backport Bot / build (push) Waiting to run
Details
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run
Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions
Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:17], map[id:ubuntu-latest name:Linux]) (push) Waiting to run
Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:21], map[id:ubuntu-latest name:Linux]) (push) Waiting to run
Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:23], map[id:ubuntu-latest name:Linux]) (push) Waiting to run
Details
Deploy Docs / Dispatch docs deployment (push) Waiting to run
Details
Backport Bot / build (push) Waiting to run
Details
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run
Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions
Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:false version:17], map[id:ubuntu-latest name:Linux]) (push) Waiting to run
Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:21], map[id:ubuntu-latest name:Linux]) (push) Waiting to run
Details
CI / ${{ matrix.os.name}} | Java ${{ matrix.java.version}} (map[toolchain:true version:23], map[id:ubuntu-latest name:Linux]) (push) Waiting to run
Details
Deploy Docs / Dispatch docs deployment (push) Waiting to run
Details
Prior to this commit, a BeanDefinitionReader registered via @ImportResource was required to be public and have a public constructor that accepts a single BeanDefinitionRegistry. However, the public visibility requirements are not necessary, and the requirements for the constructor's formal parameter list is not documented. To address those issues, this commit removes the public visibility restrictions and documents that a BeanDefinitionReader registered via @ImportResource must declare a constructor that accepts a single BeanDefinitionRegistry. In addition, this commit includes the cause of the instantiation failure in case the registered BeanDefinitionReader cannot be instantiated. Closes gh-34928
This commit is contained in:
parent
98cef503fb
commit
d890a38f3c
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -27,6 +28,7 @@ import java.util.Set;
|
|||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
|
||||
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
|
||||
|
@ -371,9 +373,11 @@ class ConfigurationClassBeanDefinitionReader {
|
|||
BeanDefinitionReader reader = readerInstanceCache.get(readerClass);
|
||||
if (reader == null) {
|
||||
try {
|
||||
Constructor<? extends BeanDefinitionReader> constructor =
|
||||
readerClass.getDeclaredConstructor(BeanDefinitionRegistry.class);
|
||||
// Instantiate the specified BeanDefinitionReader
|
||||
reader = readerClass.getConstructor(BeanDefinitionRegistry.class).newInstance(this.registry);
|
||||
// Delegate the current ResourceLoader to it if possible
|
||||
reader = BeanUtils.instantiateClass(constructor, this.registry);
|
||||
// Delegate the current ResourceLoader and Environment to it if possible
|
||||
if (reader instanceof AbstractBeanDefinitionReader abdr) {
|
||||
abdr.setResourceLoader(this.resourceLoader);
|
||||
abdr.setEnvironment(this.environment);
|
||||
|
@ -382,7 +386,7 @@ class ConfigurationClassBeanDefinitionReader {
|
|||
}
|
||||
catch (Throwable ex) {
|
||||
throw new IllegalStateException(
|
||||
"Could not instantiate BeanDefinitionReader class [" + readerClass.getName() + "]");
|
||||
"Could not instantiate BeanDefinitionReader class [" + readerClass.getName() + "]", ex);
|
||||
}
|
||||
}
|
||||
reader.loadBeanDefinitions(resource);
|
||||
|
|
|
@ -80,6 +80,10 @@ public @interface ImportResource {
|
|||
* {@link BeanDefinitionReader} implementation to use when processing
|
||||
* resources specified via the {@link #locations() locations} or
|
||||
* {@link #value() value} attribute.
|
||||
* <p>The configured {@code BeanDefinitionReader} type must declare a
|
||||
* constructor that accepts a single
|
||||
* {@link org.springframework.beans.factory.support.BeanDefinitionRegistry
|
||||
* BeanDefinitionRegistry} argument.
|
||||
* <p>By default, the reader will be adapted to the resource path specified:
|
||||
* {@code ".groovy"} files will be processed with a
|
||||
* {@link org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.junit.jupiter.api.Test;
|
|||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
@ -109,6 +110,13 @@ class ImportResourceTests {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void importResourceWithPrivateReader() {
|
||||
try (AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ImportWithPrivateReaderConfig.class)) {
|
||||
assertThat(ctx.containsBean("propertiesDeclaredBean")).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@ImportResource("classpath:org/springframework/context/annotation/configuration/ImportXmlConfig-context.xml")
|
||||
|
@ -173,4 +181,20 @@ class ImportResourceTests {
|
|||
static class ImportNonXmlResourceConfig {
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Configuration
|
||||
@ImportResource(locations = "org/springframework/context/annotation/configuration/ImportNonXmlResourceConfig.properties",
|
||||
reader = PrivatePropertiesBeanDefinitionReader.class)
|
||||
static class ImportWithPrivateReaderConfig {
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static class PrivatePropertiesBeanDefinitionReader
|
||||
extends org.springframework.beans.factory.support.PropertiesBeanDefinitionReader {
|
||||
|
||||
PrivatePropertiesBeanDefinitionReader(BeanDefinitionRegistry registry) {
|
||||
super(registry);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue