Skip to content

Commit cba355a

Browse files
MichelSchudelsdeleuze
authored andcommitted
Fix XML parser default value handling
The xml parser does not fill in defaults provided in the XSD when validation is disabled. As a result, attributes like default-lazy-init will not receive the value "default" but an empty string. With this commit, BeanDefinitionParserDelegate now takes this into account, checking default values against empty string as well as "default". As a consequence, default-lazy-init attribute should now work correctly even when the XSD validation is disabled. Issue: SPR-8335
1 parent 124e817 commit cba355a

File tree

2 files changed

+59
-9
lines changed

2 files changed

+59
-9
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java

+12-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -320,21 +320,21 @@ public void initDefaults(Element root, @Nullable BeanDefinitionParserDelegate pa
320320
*/
321321
protected void populateDefaults(DocumentDefaultsDefinition defaults, @Nullable DocumentDefaultsDefinition parentDefaults, Element root) {
322322
String lazyInit = root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE);
323-
if (DEFAULT_VALUE.equals(lazyInit)) {
323+
if (isDefaultValue(lazyInit)) {
324324
// Potentially inherited from outer <beans> sections, otherwise falling back to false.
325325
lazyInit = (parentDefaults != null ? parentDefaults.getLazyInit() : FALSE_VALUE);
326326
}
327327
defaults.setLazyInit(lazyInit);
328328

329329
String merge = root.getAttribute(DEFAULT_MERGE_ATTRIBUTE);
330-
if (DEFAULT_VALUE.equals(merge)) {
330+
if (isDefaultValue(merge)) {
331331
// Potentially inherited from outer <beans> sections, otherwise falling back to false.
332332
merge = (parentDefaults != null ? parentDefaults.getMerge() : FALSE_VALUE);
333333
}
334334
defaults.setMerge(merge);
335335

336336
String autowire = root.getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE);
337-
if (DEFAULT_VALUE.equals(autowire)) {
337+
if (isDefaultValue(autowire)) {
338338
// Potentially inherited from outer <beans> sections, otherwise falling back to 'no'.
339339
autowire = (parentDefaults != null ? parentDefaults.getAutowire() : AUTOWIRE_NO_VALUE);
340340
}
@@ -572,7 +572,7 @@ else if (containingBean != null) {
572572
}
573573

574574
String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
575-
if (DEFAULT_VALUE.equals(lazyInit)) {
575+
if (isDefaultValue(lazyInit)) {
576576
lazyInit = this.defaults.getLazyInit();
577577
}
578578
bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
@@ -586,7 +586,7 @@ else if (containingBean != null) {
586586
}
587587

588588
String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
589-
if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate)) {
589+
if (isDefaultValue(autowireCandidate)) {
590590
String candidatePattern = this.defaults.getAutowireCandidates();
591591
if (candidatePattern != null) {
592592
String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
@@ -661,7 +661,7 @@ public void parseMetaElements(Element ele, BeanMetadataAttributeAccessor attribu
661661
@SuppressWarnings("deprecation")
662662
public int getAutowireMode(String attValue) {
663663
String att = attValue;
664-
if (DEFAULT_VALUE.equals(att)) {
664+
if (isDefaultValue(att)) {
665665
att = this.defaults.getAutowire();
666666
}
667667
int autowire = AbstractBeanDefinition.AUTOWIRE_NO;
@@ -1341,7 +1341,7 @@ public Properties parsePropsElement(Element propsEle) {
13411341
*/
13421342
public boolean parseMergeAttribute(Element collectionElement) {
13431343
String value = collectionElement.getAttribute(MERGE_ATTRIBUTE);
1344-
if (DEFAULT_VALUE.equals(value)) {
1344+
if (isDefaultValue(value)) {
13451345
value = this.defaults.getMerge();
13461346
}
13471347
return TRUE_VALUE.equals(value);
@@ -1481,6 +1481,10 @@ public boolean isDefaultNamespace(Node node) {
14811481
return isDefaultNamespace(getNamespaceURI(node));
14821482
}
14831483

1484+
private boolean isDefaultValue(String value) {
1485+
return (DEFAULT_VALUE.equals(value) || "".equals(value));
1486+
}
1487+
14841488
private boolean isCandidateElement(Node node) {
14851489
return (node instanceof Element && (isDefaultNamespace(node) || !isDefaultNamespace(node.getParentNode())));
14861490
}

spring-beans/src/test/java/org/springframework/beans/factory/xml/NestedBeansElementAttributeRecursionTests.java

+47-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -41,6 +41,21 @@ public void defaultLazyInit() {
4141
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
4242
new ClassPathResource("NestedBeansElementAttributeRecursionTests-lazy-context.xml", this.getClass()));
4343

44+
assertLazyInits(bf);
45+
}
46+
47+
@Test
48+
public void defaultLazyInitWithNonValidatingParser() {
49+
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
50+
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(bf);
51+
xmlBeanDefinitionReader.setValidating(false);
52+
xmlBeanDefinitionReader.loadBeanDefinitions(
53+
new ClassPathResource("NestedBeansElementAttributeRecursionTests-lazy-context.xml", this.getClass()));
54+
55+
assertLazyInits(bf);
56+
}
57+
58+
private void assertLazyInits(DefaultListableBeanFactory bf) {
4459
BeanDefinition foo = bf.getBeanDefinition("foo");
4560
BeanDefinition bar = bf.getBeanDefinition("bar");
4661
BeanDefinition baz = bf.getBeanDefinition("baz");
@@ -61,6 +76,22 @@ public void defaultMerge() {
6176
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
6277
new ClassPathResource("NestedBeansElementAttributeRecursionTests-merge-context.xml", this.getClass()));
6378

79+
assertMerge(bf);
80+
}
81+
82+
@Test
83+
@SuppressWarnings("unchecked")
84+
public void defaultMergeWithNonValidatingParser() {
85+
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
86+
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(bf);
87+
xmlBeanDefinitionReader.setValidating(false);
88+
xmlBeanDefinitionReader.loadBeanDefinitions(
89+
new ClassPathResource("NestedBeansElementAttributeRecursionTests-merge-context.xml", this.getClass()));
90+
91+
assertMerge(bf);
92+
}
93+
94+
private void assertMerge(DefaultListableBeanFactory bf) {
6495
TestBean topLevel = bf.getBean("topLevelConcreteTestBean", TestBean.class);
6596
// has the concrete child bean values
6697
assertThat((Iterable<String>) topLevel.getSomeList(), hasItems("charlie", "delta"));
@@ -84,6 +115,21 @@ public void defaultAutowireCandidates() {
84115
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
85116
new ClassPathResource("NestedBeansElementAttributeRecursionTests-autowire-candidates-context.xml", this.getClass()));
86117

118+
assertAutowireCandidates(bf);
119+
}
120+
121+
@Test
122+
public void defaultAutowireCandidatesWithNonValidatingParser() {
123+
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
124+
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(bf);
125+
xmlBeanDefinitionReader.setValidating(false);
126+
xmlBeanDefinitionReader.loadBeanDefinitions(
127+
new ClassPathResource("NestedBeansElementAttributeRecursionTests-autowire-candidates-context.xml", this.getClass()));
128+
129+
assertAutowireCandidates(bf);
130+
}
131+
132+
private void assertAutowireCandidates(DefaultListableBeanFactory bf) {
87133
assertThat(bf.getBeanDefinition("fooService").isAutowireCandidate(), is(true));
88134
assertThat(bf.getBeanDefinition("fooRepository").isAutowireCandidate(), is(true));
89135
assertThat(bf.getBeanDefinition("other").isAutowireCandidate(), is(false));

0 commit comments

Comments
 (0)