Skip to content

Commit 21d3bf8

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 ce05a5b commit 21d3bf8

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

Lines changed: 12 additions & 8 deletions
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.
@@ -340,21 +340,21 @@ public void initDefaults(Element root, BeanDefinitionParserDelegate parent) {
340340
*/
341341
protected void populateDefaults(DocumentDefaultsDefinition defaults, DocumentDefaultsDefinition parentDefaults, Element root) {
342342
String lazyInit = root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE);
343-
if (DEFAULT_VALUE.equals(lazyInit)) {
343+
if (isDefaultValue(lazyInit)) {
344344
// Potentially inherited from outer <beans> sections, otherwise falling back to false.
345345
lazyInit = (parentDefaults != null ? parentDefaults.getLazyInit() : FALSE_VALUE);
346346
}
347347
defaults.setLazyInit(lazyInit);
348348

349349
String merge = root.getAttribute(DEFAULT_MERGE_ATTRIBUTE);
350-
if (DEFAULT_VALUE.equals(merge)) {
350+
if (isDefaultValue(merge)) {
351351
// Potentially inherited from outer <beans> sections, otherwise falling back to false.
352352
merge = (parentDefaults != null ? parentDefaults.getMerge() : FALSE_VALUE);
353353
}
354354
defaults.setMerge(merge);
355355

356356
String autowire = root.getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE);
357-
if (DEFAULT_VALUE.equals(autowire)) {
357+
if (isDefaultValue(autowire)) {
358358
// Potentially inherited from outer <beans> sections, otherwise falling back to 'no'.
359359
autowire = (parentDefaults != null ? parentDefaults.getAutowire() : AUTOWIRE_NO_VALUE);
360360
}
@@ -593,7 +593,7 @@ else if (containingBean != null) {
593593
}
594594

595595
String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
596-
if (DEFAULT_VALUE.equals(lazyInit)) {
596+
if (isDefaultValue(lazyInit)) {
597597
lazyInit = this.defaults.getLazyInit();
598598
}
599599
bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
@@ -610,7 +610,7 @@ else if (containingBean != null) {
610610
}
611611

612612
String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
613-
if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate)) {
613+
if (isDefaultValue(autowireCandidate)) {
614614
String candidatePattern = this.defaults.getAutowireCandidates();
615615
if (candidatePattern != null) {
616616
String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
@@ -691,7 +691,7 @@ public void parseMetaElements(Element ele, BeanMetadataAttributeAccessor attribu
691691
@SuppressWarnings("deprecation")
692692
public int getAutowireMode(String attValue) {
693693
String att = attValue;
694-
if (DEFAULT_VALUE.equals(att)) {
694+
if (isDefaultValue(att)) {
695695
att = this.defaults.getAutowire();
696696
}
697697
int autowire = AbstractBeanDefinition.AUTOWIRE_NO;
@@ -1390,7 +1390,7 @@ public Properties parsePropsElement(Element propsEle) {
13901390
*/
13911391
public boolean parseMergeAttribute(Element collectionElement) {
13921392
String value = collectionElement.getAttribute(MERGE_ATTRIBUTE);
1393-
if (DEFAULT_VALUE.equals(value)) {
1393+
if (isDefaultValue(value)) {
13941394
value = this.defaults.getMerge();
13951395
}
13961396
return TRUE_VALUE.equals(value);
@@ -1519,6 +1519,10 @@ public boolean isDefaultNamespace(Node node) {
15191519
return isDefaultNamespace(getNamespaceURI(node));
15201520
}
15211521

1522+
private boolean isDefaultValue(String value) {
1523+
return (DEFAULT_VALUE.equals(value) || "".equals(value));
1524+
}
1525+
15221526
private boolean isCandidateElement(Node node) {
15231527
return (node instanceof Element && (isDefaultNamespace(node) || !isDefaultNamespace(node.getParentNode())));
15241528
}

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

Lines changed: 47 additions & 1 deletion
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)