Disable XML reader when spring.xml.ignore is true

This commit allows to set the XmlBeanDefinitionReader field from
BeanDefinitionLoader to null in a way that allows the GraalVM native
compiler to remove it from the native image when the spring.xml.ignore
flag introduced by spring-projects/spring-framework#25151
is set to true.

The purpose of this change is to allow smaller footprint on native
images without requiring to use GraalVM native substitutions
which are unmaintainable by nature and also to increase the consistency
between JVM and native images.

In order to effective, this optimization requires BeanDefinitionLoader
class to be initialized at build time.

See gh-22093
pull/22113/head
Sébastien Deleuze 4 years ago committed by Andy Wilkinson
parent ea30c096dd
commit 8d5cf79675

@ -32,6 +32,7 @@ import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader; import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner; import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.core.SpringProperties;
import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
@ -53,17 +54,27 @@ import org.springframework.util.StringUtils;
* *
* @author Phillip Webb * @author Phillip Webb
* @author Vladislav Kisel * @author Vladislav Kisel
* @author Sebastien Deleuze
* @see #setBeanNameGenerator(BeanNameGenerator) * @see #setBeanNameGenerator(BeanNameGenerator)
*/ */
class BeanDefinitionLoader { class BeanDefinitionLoader {
/**
* Boolean flag controlled by a {@code spring.xml.ignore} system property that
* instructs Spring to ignore XML, i.e. to not initialize the XML-related
* infrastructure.
* <p>
* By default XML support is enabled.
*/
private static final boolean IS_XML_ENABLED = !SpringProperties.getFlag("spring.xml.ignore");
private final Object[] sources; private final Object[] sources;
private final AnnotatedBeanDefinitionReader annotatedReader; private final AnnotatedBeanDefinitionReader annotatedReader;
private final XmlBeanDefinitionReader xmlReader; private final XmlBeanDefinitionReader xmlReader;
private BeanDefinitionReader groovyReader; private final BeanDefinitionReader groovyReader;
private final ClassPathBeanDefinitionScanner scanner; private final ClassPathBeanDefinitionScanner scanner;
@ -80,10 +91,8 @@ class BeanDefinitionLoader {
Assert.notEmpty(sources, "Sources must not be empty"); Assert.notEmpty(sources, "Sources must not be empty");
this.sources = sources; this.sources = sources;
this.annotatedReader = new AnnotatedBeanDefinitionReader(registry); this.annotatedReader = new AnnotatedBeanDefinitionReader(registry);
this.xmlReader = new XmlBeanDefinitionReader(registry); this.xmlReader = (IS_XML_ENABLED ? new XmlBeanDefinitionReader(registry) : null);
if (isGroovyPresent()) { this.groovyReader = (isGroovyPresent() ? new GroovyBeanDefinitionReader(registry) : null);
this.groovyReader = new GroovyBeanDefinitionReader(registry);
}
this.scanner = new ClassPathBeanDefinitionScanner(registry); this.scanner = new ClassPathBeanDefinitionScanner(registry);
this.scanner.addExcludeFilter(new ClassExcludeFilter(sources)); this.scanner.addExcludeFilter(new ClassExcludeFilter(sources));
} }
@ -94,8 +103,10 @@ class BeanDefinitionLoader {
*/ */
void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) { void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
this.annotatedReader.setBeanNameGenerator(beanNameGenerator); this.annotatedReader.setBeanNameGenerator(beanNameGenerator);
this.xmlReader.setBeanNameGenerator(beanNameGenerator);
this.scanner.setBeanNameGenerator(beanNameGenerator); this.scanner.setBeanNameGenerator(beanNameGenerator);
if (IS_XML_ENABLED) {
this.xmlReader.setBeanNameGenerator(beanNameGenerator);
}
} }
/** /**
@ -104,8 +115,10 @@ class BeanDefinitionLoader {
*/ */
void setResourceLoader(ResourceLoader resourceLoader) { void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader; this.resourceLoader = resourceLoader;
this.xmlReader.setResourceLoader(resourceLoader);
this.scanner.setResourceLoader(resourceLoader); this.scanner.setResourceLoader(resourceLoader);
if (IS_XML_ENABLED) {
this.xmlReader.setResourceLoader(resourceLoader);
}
} }
/** /**
@ -114,8 +127,10 @@ class BeanDefinitionLoader {
*/ */
void setEnvironment(ConfigurableEnvironment environment) { void setEnvironment(ConfigurableEnvironment environment) {
this.annotatedReader.setEnvironment(environment); this.annotatedReader.setEnvironment(environment);
this.xmlReader.setEnvironment(environment);
this.scanner.setEnvironment(environment); this.scanner.setEnvironment(environment);
if (IS_XML_ENABLED) {
this.xmlReader.setEnvironment(environment);
}
} }
/** /**
@ -167,6 +182,9 @@ class BeanDefinitionLoader {
this.groovyReader.loadBeanDefinitions(source); this.groovyReader.loadBeanDefinitions(source);
} }
else { else {
if (!IS_XML_ENABLED) {
throw new BeanDefinitionStoreException("Cannot load resources when XML support is disabled");
}
this.xmlReader.loadBeanDefinitions(source); this.xmlReader.loadBeanDefinitions(source);
} }
} }

Loading…
Cancel
Save