0
# XML Configuration Support
1
2
Extensible XML parsing framework with namespace support, custom schema handling, and comprehensive bean definition loading from XML configuration files. This system enables declarative configuration of Spring beans through XML files with support for custom namespaces and validation.
3
4
## Capabilities
5
6
### XML Bean Definition Reader
7
8
Core class for reading bean definitions from XML configuration files with support for validation, namespace handling, and custom schema resolution.
9
10
```java { .api }
11
/**
12
* Bean definition reader for XML bean definitions, using a SAX parser under the hood.
13
*/
14
class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
15
/** Indicates that no validation should be performed. */
16
public static final int VALIDATION_NONE = XmlValidationModeDetector.VALIDATION_NONE;
17
/** Indicates that an XSD should be used for validation if a schema declaration is found. */
18
public static final int VALIDATION_AUTO = XmlValidationModeDetector.VALIDATION_AUTO;
19
/** Indicates that DTD validation should be performed. */
20
public static final int VALIDATION_DTD = XmlValidationModeDetector.VALIDATION_DTD;
21
/** Indicates that XSD validation should be performed. */
22
public static final int VALIDATION_XSD = XmlValidationModeDetector.VALIDATION_XSD;
23
24
/**
25
* Create new XmlBeanDefinitionReader for the given bean factory.
26
* @param registry the BeanFactory to load bean definitions into
27
*/
28
public XmlBeanDefinitionReader(BeanDefinitionRegistry registry);
29
30
/**
31
* Set whether to use XML validation.
32
* @param validating whether to validate; switches off validation otherwise
33
*/
34
public void setValidating(boolean validating);
35
36
/**
37
* Set the validation mode to use by name.
38
* @param validationModeName the validation mode name
39
*/
40
public void setValidationModeName(String validationModeName);
41
42
/**
43
* Set the validation mode to use.
44
* @param validationMode the validation mode
45
*/
46
public void setValidationMode(int validationMode);
47
48
/**
49
* Return the validation mode to use.
50
* @return the validation mode
51
*/
52
public int getValidationMode();
53
54
/**
55
* Set whether or not the XML parser should be XML namespace aware.
56
* @param namespaceAware the default is false
57
*/
58
public void setNamespaceAware(boolean namespaceAware);
59
60
/**
61
* Return whether or not the XML parser should be XML namespace aware.
62
* @return true if namespace aware
63
*/
64
public boolean isNamespaceAware();
65
66
/**
67
* Set an implementation of the ProblemReporter interface to use.
68
* @param problemReporter the desired ProblemReporter implementation
69
*/
70
public void setProblemReporter(ProblemReporter problemReporter);
71
72
/**
73
* Set an implementation of the ReaderEventListener interface to use.
74
* @param eventListener the desired ReaderEventListener implementation
75
*/
76
public void setEventListener(ReaderEventListener eventListener);
77
78
/**
79
* Set the SourceExtractor to use for generated bean definitions that correspond to top-level beans.
80
* @param sourceExtractor the desired SourceExtractor implementation
81
*/
82
public void setSourceExtractor(SourceExtractor sourceExtractor);
83
84
/**
85
* Set the NamespaceHandlerResolver to use.
86
* @param namespaceHandlerResolver the desired NamespaceHandlerResolver implementation
87
*/
88
public void setNamespaceHandlerResolver(NamespaceHandlerResolver namespaceHandlerResolver);
89
90
/**
91
* Set the DocumentLoader to use for loading XML documents.
92
* @param documentLoader the desired DocumentLoader implementation
93
*/
94
public void setDocumentLoader(DocumentLoader documentLoader);
95
96
/**
97
* Set the EntityResolver to use for resolving DTDs and schemas.
98
* @param entityResolver the desired EntityResolver implementation
99
*/
100
public void setEntityResolver(EntityResolver entityResolver);
101
102
/**
103
* Set the ErrorHandler to use for handling XML parsing errors.
104
* @param errorHandler the desired ErrorHandler implementation
105
*/
106
public void setErrorHandler(ErrorHandler errorHandler);
107
108
/**
109
* Load bean definitions from the specified XML file.
110
* @param resource the resource descriptor for the XML file
111
* @return the number of bean definitions found
112
* @throws BeanDefinitionStoreException in case of loading or parsing errors
113
*/
114
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException;
115
116
/**
117
* Load bean definitions from the specified XML file.
118
* @param encodedResource the resource descriptor for the XML file, allowing to specify an encoding to use for parsing the file
119
* @return the number of bean definitions found
120
* @throws BeanDefinitionStoreException in case of loading or parsing errors
121
*/
122
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException;
123
124
/**
125
* Load bean definitions from the specified XML file.
126
* @param inputSource the SAX InputSource to read from
127
* @return the number of bean definitions found
128
* @throws BeanDefinitionStoreException in case of loading or parsing errors
129
*/
130
public int loadBeanDefinitions(InputSource inputSource) throws BeanDefinitionStoreException;
131
132
/**
133
* Load bean definitions from the specified XML file.
134
* @param inputSource the SAX InputSource to read from
135
* @param resource the resource descriptor for the XML file
136
* @return the number of bean definitions found
137
* @throws BeanDefinitionStoreException in case of loading or parsing errors
138
*/
139
public int loadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException;
140
}
141
```
142
143
### Bean Definition Document Reader
144
145
Interface and implementation for reading bean definitions from XML documents.
146
147
```java { .api }
148
/**
149
* SPI for parsing an XML document that contains Spring bean definitions.
150
*/
151
interface BeanDefinitionDocumentReader {
152
/**
153
* Read bean definitions from the given DOM document and register them with the given bean definition registry.
154
* @param doc the DOM document
155
* @param readerContext the current context of the reader (includes the target registry and the resource being parsed)
156
* @throws BeanDefinitionStoreException in case of parsing errors
157
*/
158
void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) throws BeanDefinitionStoreException;
159
}
160
161
/**
162
* Default implementation of BeanDefinitionDocumentReader that reads bean definitions according to the "spring-beans" DTD and XSD format.
163
*/
164
class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader {
165
/** Constant for the "bean" element. */
166
public static final String BEAN_ELEMENT = BeanDefinitionParserDelegate.BEAN_ELEMENT;
167
/** Constant for the "beans" element. */
168
public static final String NESTED_BEANS_ELEMENT = "beans";
169
/** Constant for the "alias" element. */
170
public static final String ALIAS_ELEMENT = "alias";
171
/** Constant for the "name" attribute. */
172
public static final String NAME_ATTRIBUTE = "name";
173
/** Constant for the "alias" attribute. */
174
public static final String ALIAS_ATTRIBUTE = "alias";
175
/** Constant for the "import" element. */
176
public static final String IMPORT_ELEMENT = "import";
177
/** Constant for the "resource" attribute. */
178
public static final String RESOURCE_ATTRIBUTE = "resource";
179
/** Constant for the "profile" attribute. */
180
public static final String PROFILE_ATTRIBUTE = "profile";
181
182
/**
183
* This implementation parses bean definitions according to the "spring-beans" XSD (or DTD, historically).
184
* @param doc the DOM document
185
* @param readerContext the current context of the reader
186
*/
187
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext);
188
}
189
```
190
191
### Bean Definition Parser Delegate
192
193
Stateful delegate class used to parse XML bean definitions.
194
195
```java { .api }
196
/**
197
* Stateful delegate class used to parse XML bean definitions.
198
*/
199
class BeanDefinitionParserDelegate {
200
/** Constant for the Spring beans namespace URI. */
201
public static final String BEANS_NAMESPACE_URI = "http://www.springframework.org/schema/beans";
202
/** Constant for the default delimiters for multiple values in a single attribute. */
203
public static final String MULTI_VALUE_ATTRIBUTE_DELIMITERS = ",; ";
204
/** Constant for the "true" value. */
205
public static final String TRUE_VALUE = "true";
206
/** Constant for the "false" value. */
207
public static final String FALSE_VALUE = "false";
208
/** Constant for the "default" value. */
209
public static final String DEFAULT_VALUE = "default";
210
/** Constant for the "bean" element. */
211
public static final String BEAN_ELEMENT = "bean";
212
/** Constant for the "description" element. */
213
public static final String DESCRIPTION_ELEMENT = "description";
214
/** Constant for the "import" element. */
215
public static final String IMPORT_ELEMENT = "import";
216
/** Constant for the "alias" element. */
217
public static final String ALIAS_ELEMENT = "alias";
218
219
/**
220
* Create a new BeanDefinitionParserDelegate associated with the supplied XmlReaderContext.
221
* @param readerContext the XML reader context
222
*/
223
public BeanDefinitionParserDelegate(XmlReaderContext readerContext);
224
225
/**
226
* Get the XmlReaderContext associated with this delegate.
227
* @return the XmlReaderContext
228
*/
229
public final XmlReaderContext getReaderContext();
230
231
/**
232
* Initialize the default lazy-init, autowire, dependency check settings, init-method, destroy-method and merge settings.
233
* @param root the root element of the current bean definition document (or nested beans element)
234
*/
235
public void initDefaults(Element root);
236
237
/**
238
* Initialize the default settings.
239
* @param root the root element of the current bean definition document (or nested beans element)
240
* @param parent the parent bean definition parser delegate (if any)
241
*/
242
public void initDefaults(Element root, BeanDefinitionParserDelegate parent);
243
244
/**
245
* Return the defaults definition object.
246
* @return the defaults definition object
247
*/
248
public DocumentDefaultsDefinition getDefaults();
249
250
/**
251
* Return the default settings for bean definitions as BeanDefinitionDefaults object.
252
* @return the BeanDefinitionDefaults object
253
*/
254
public BeanDefinitionDefaults getBeanDefinitionDefaults();
255
256
/**
257
* Return any patterns provided in the 'default-autowire-candidates' attribute of the top-level beans element.
258
* @return the autowire candidate patterns, or null if none specified
259
*/
260
public String[] getAutowireCandidatePatterns();
261
262
/**
263
* Parses the supplied Element and creates a BeanDefinition by delegating to the createBeanDefinition method.
264
* @param ele the element that is to be parsed into a BeanDefinition
265
* @return the BeanDefinition
266
*/
267
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele);
268
269
/**
270
* Parses the supplied Element and creates a BeanDefinition by delegating to the createBeanDefinition method.
271
* @param ele the element that is to be parsed into a BeanDefinition
272
* @param containingBean the containing bean definition (if any)
273
* @return the BeanDefinition
274
*/
275
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean);
276
277
/**
278
* Create a bean definition for the given class name and parent name.
279
* @param className the name of the bean class
280
* @param parentName the name of the parent bean
281
* @return the newly created bean definition
282
* @throws ClassNotFoundException if bean class resolution was attempted but failed
283
*/
284
public AbstractBeanDefinition createBeanDefinition(String className, String parentName) throws ClassNotFoundException;
285
286
/**
287
* Parse the meta elements underneath the given element, if any.
288
* @param ele the DOM element we're parsing
289
* @param attributeAccessor the BeanMetadataAttributeAccessor to attach the metadata to
290
*/
291
public void parseMetaElements(Element ele, BeanMetadataAttributeAccessor attributeAccessor);
292
293
/**
294
* Parse the lookup-method elements.
295
* @param beanElement the current bean element
296
* @param bd the current bean definition
297
*/
298
public void parseLookupOverrideSubElements(Element beanElement, MethodOverrides overrides);
299
300
/**
301
* Parse replaced-method elements.
302
* @param beanElement the current bean element
303
* @param bd the current bean definition
304
*/
305
public void parseReplacedMethodSubElements(Element beanElement, MethodOverrides overrides);
306
307
/**
308
* Parse constructor-arg elements.
309
* @param beanElement the current bean element
310
* @param bd the current bean definition
311
*/
312
public void parseConstructorArgElements(Element beanElement, BeanDefinition bd);
313
314
/**
315
* Parse property elements.
316
* @param beanElement the current bean element
317
* @param bd the current bean definition
318
*/
319
public void parsePropertyElements(Element beanElement, BeanDefinition bd);
320
321
/**
322
* Parse qualifier elements.
323
* @param beanElement the current bean element
324
* @param bd the current bean definition
325
*/
326
public void parseQualifierElements(Element beanElement, AbstractBeanDefinition bd);
327
328
/**
329
* Get the value of a property element.
330
* @param ele the property element
331
* @param bd the current bean definition
332
* @param propertyName the name of the property represented by this element
333
* @return the Object value
334
*/
335
public Object parsePropertyValue(Element ele, BeanDefinition bd, String propertyName);
336
337
/**
338
* Parse a value, ref or any of the collection elements.
339
* @param ele the current property element
340
* @param bd the current bean definition
341
* @return the parsed Object
342
*/
343
public Object parsePropertySubElement(Element ele, BeanDefinition bd);
344
345
/**
346
* Parse a value, ref or any of the collection elements.
347
* @param ele the current property element
348
* @param bd the current bean definition
349
* @param defaultValueType the default type (class name) for any <value> tag that might be created
350
* @return the parsed Object
351
*/
352
public Object parsePropertySubElement(Element ele, BeanDefinition bd, String defaultValueType);
353
}
354
```
355
356
### Namespace Handler Support
357
358
Framework for handling custom XML namespaces in Spring configuration files.
359
360
```java { .api }
361
/**
362
* Base interface used by the DefaultBeanDefinitionDocumentReader for handling custom namespaces in a Spring XML configuration file.
363
*/
364
interface NamespaceHandler {
365
/**
366
* Invoked by the DefaultBeanDefinitionDocumentReader after construction but before any custom elements are parsed.
367
*/
368
void init();
369
370
/**
371
* Parse the specified Element and register any resulting BeanDefinitions with the BeanDefinitionRegistry that is embedded in the supplied ParserContext.
372
* @param element the element that is to be parsed into one or more BeanDefinitions
373
* @param parserContext the object encapsulating the current state of the parsing process
374
* @return the primary BeanDefinition (can be null as explained above)
375
*/
376
BeanDefinition parse(Element element, ParserContext parserContext);
377
378
/**
379
* Parse the specified Node and decorate the supplied BeanDefinitionHolder, returning the decorated definition.
380
* @param node the source element or attribute that is to be parsed
381
* @param definition the current bean definition
382
* @param parserContext the object encapsulating the current state of the parsing process
383
* @return the decorated definition (to be registered in the BeanFactory), or simply the original bean definition if no decoration is required
384
*/
385
BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext);
386
}
387
388
/**
389
* Support class for implementing custom NamespaceHandlers.
390
*/
391
abstract class NamespaceHandlerSupport implements NamespaceHandler {
392
/**
393
* Parses the supplied Element by delegating to the BeanDefinitionParser that is registered for that Element.
394
* @param element the element that is to be parsed into one or more BeanDefinitions
395
* @param parserContext the object encapsulating the current state of the parsing process
396
* @return the primary BeanDefinition resulting from the parsing of the supplied Element
397
*/
398
public BeanDefinition parse(Element element, ParserContext parserContext);
399
400
/**
401
* Decorates the supplied Node by delegating to the BeanDefinitionDecorator that is registered to handle that Node.
402
* @param node the source element or attribute that is to be parsed
403
* @param definition the current bean definition
404
* @param parserContext the object encapsulating the current state of the parsing process
405
* @return the decorated definition
406
*/
407
public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext);
408
409
/**
410
* Subclasses can call this to register the supplied BeanDefinitionParser to handle the specified element.
411
* @param elementName the name of the element that the parser handles
412
* @param parser the parser instance
413
*/
414
protected final void registerBeanDefinitionParser(String elementName, BeanDefinitionParser parser);
415
416
/**
417
* Subclasses can call this to register the supplied BeanDefinitionDecorator to handle the specified element.
418
* @param elementName the name of the element that the decorator handles
419
* @param decorator the decorator instance
420
*/
421
protected final void registerBeanDefinitionDecorator(String elementName, BeanDefinitionDecorator decorator);
422
423
/**
424
* Subclasses can call this to register the supplied BeanDefinitionDecorator to handle the specified attribute.
425
* @param attrName the name of the attribute that the decorator handles
426
* @param decorator the decorator instance
427
*/
428
protected final void registerBeanDefinitionDecoratorForAttribute(String attrName, BeanDefinitionDecorator decorator);
429
}
430
431
/**
432
* Interface used by the DefaultBeanDefinitionDocumentReader to locate a NamespaceHandler implementation for a particular namespace URI.
433
*/
434
interface NamespaceHandlerResolver {
435
/**
436
* Resolve the namespace URI and return the located NamespaceHandler implementation.
437
* @param namespaceUri the relevant namespace URI
438
* @return the located NamespaceHandler (may be null)
439
*/
440
NamespaceHandler resolve(String namespaceUri);
441
}
442
443
/**
444
* Default implementation of the NamespaceHandlerResolver interface.
445
*/
446
class DefaultNamespaceHandlerResolver implements NamespaceHandlerResolver {
447
/** The location to look for the mapping files. Can be present in multiple JAR files. */
448
public static final String DEFAULT_HANDLER_MAPPINGS_LOCATION = "META-INF/spring.handlers";
449
450
/**
451
* Create a new DefaultNamespaceHandlerResolver using the default mapping file location.
452
*/
453
public DefaultNamespaceHandlerResolver();
454
455
/**
456
* Create a new DefaultNamespaceHandlerResolver using the default mapping file location.
457
* @param classLoader the ClassLoader instance used to load mapping resources (may be null, in which case the thread context ClassLoader will be used)
458
*/
459
public DefaultNamespaceHandlerResolver(ClassLoader classLoader);
460
461
/**
462
* Create a new DefaultNamespaceHandlerResolver using the supplied mapping file location.
463
* @param classLoader the ClassLoader instance used to load mapping resources (may be null, in which case the thread context ClassLoader will be used)
464
* @param handlerMappingsLocation the mapping file location
465
*/
466
public DefaultNamespaceHandlerResolver(ClassLoader classLoader, String handlerMappingsLocation);
467
468
/**
469
* Locate the NamespaceHandler for the supplied namespace URI from the configured mappings.
470
* @param namespaceUri the relevant namespace URI
471
* @return the located NamespaceHandler; returns null if no NamespaceHandler could be found for the given namespace URI
472
*/
473
public NamespaceHandler resolve(String namespaceUri);
474
}
475
```
476
477
### Bean Definition Parser Framework
478
479
Framework for creating custom bean definition parsers for XML configuration.
480
481
```java { .api }
482
/**
483
* Interface used by the BeanDefinitionParserDelegate to handle custom, top-level (directly under beans) tags.
484
*/
485
interface BeanDefinitionParser {
486
/**
487
* Parse the specified Element and register the resulting BeanDefinition(s) with the ParserContext.getBeanDefinitionRegistry().
488
* @param element the element that is to be parsed into one or more BeanDefinitions
489
* @param parserContext the object encapsulating the current state of the parsing process; provides access to a BeanDefinitionRegistry
490
* @return the primary BeanDefinition resulting from the parsing of the supplied Element (can be null)
491
*/
492
BeanDefinition parse(Element element, ParserContext parserContext);
493
}
494
495
/**
496
* Interface used by the BeanDefinitionParserDelegate to handle custom, nested (directly under a bean) tags.
497
*/
498
interface BeanDefinitionDecorator {
499
/**
500
* Parse the specified Node (either an Element or an Attribute) and decorate the supplied BeanDefinitionHolder, returning the decorated definition.
501
* @param node the source element or attribute that is to be parsed
502
* @param definition the current bean definition
503
* @param parserContext the object encapsulating the current state of the parsing process
504
* @return the decorated definition (to be registered with the BeanFactory), or simply the original bean definition if no decoration is required
505
*/
506
BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext);
507
}
508
509
/**
510
* Convenient base class for BeanDefinitionParsers that need to parse and define just a single BeanDefinition.
511
*/
512
abstract class AbstractSingleBeanDefinitionParser implements BeanDefinitionParser {
513
/**
514
* Creates a BeanDefinitionBuilder instance for the bean Class and passes it to the doParse strategy method.
515
* @param element the element that is to be parsed into a single BeanDefinition
516
* @param parserContext the object encapsulating the current state of the parsing process
517
* @return the BeanDefinition resulting from the parsing of the supplied Element
518
*/
519
public final BeanDefinition parse(Element element, ParserContext parserContext);
520
521
/**
522
* Determine the bean class corresponding to the supplied Element.
523
* @param element the Element that is being parsed
524
* @return the Class of the bean that is being defined via parsing the supplied Element (must not be null)
525
*/
526
protected abstract Class<?> getBeanClass(Element element);
527
528
/**
529
* Parse the supplied Element and populate the supplied BeanDefinitionBuilder as required.
530
* @param element the XML element being parsed
531
* @param parserContext the object encapsulating the current state of the parsing process
532
* @param builder used to define the BeanDefinition
533
*/
534
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder);
535
536
/**
537
* Parse the supplied Element and populate the supplied BeanDefinitionBuilder as required.
538
* @param element the XML element being parsed
539
* @param builder used to define the BeanDefinition
540
*/
541
protected void doParse(Element element, BeanDefinitionBuilder builder);
542
543
/**
544
* Resolve the ID for the supplied BeanDefinition.
545
* @param element the element that the bean definition has been built from
546
* @param definition the bean definition to be registered
547
* @param parserContext the object encapsulating the current state of the parsing process
548
* @return the resolved id
549
* @throws BeanDefinitionStoreException if no unique name can be generated for the given bean definition
550
*/
551
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) throws BeanDefinitionStoreException;
552
553
/**
554
* Extract a bean name from the supplied Element.
555
* @param element the element that the bean definition has been built from
556
* @return the extracted bean name
557
*/
558
protected String extractBeanName(Element element);
559
560
/**
561
* Should an ID be generated instead of read from the passed in Element?
562
* @param element the element that the bean definition has been built from
563
* @return true if an ID should be generated
564
*/
565
protected boolean shouldGenerateId();
566
567
/**
568
* Should an ID be generated instead even if the passed in Element specifies an "id" attribute explicitly?
569
* @param element the element that the bean definition has been built from
570
* @return true if an ID should be generated regardless
571
*/
572
protected boolean shouldGenerateIdAsFallback();
573
}
574
575
/**
576
* Abstract BeanDefinitionParser implementation providing a number of convenience methods and a template method that subclasses must override to provide the actual parsing logic.
577
*/
578
abstract class AbstractBeanDefinitionParser implements BeanDefinitionParser {
579
/** Constant for the "id" attribute. */
580
public static final String ID_ATTRIBUTE = "id";
581
/** Constant for the "name" attribute. */
582
public static final String NAME_ATTRIBUTE = "name";
583
584
/**
585
* Central template method to actually parse the supplied Element into one or more BeanDefinitions.
586
* @param element the element that is to be parsed into one or more BeanDefinitions
587
* @param parserContext the object encapsulating the current state of the parsing process
588
* @return the primary BeanDefinition resulting from the parsing of the supplied Element
589
*/
590
public final BeanDefinition parse(Element element, ParserContext parserContext);
591
592
/**
593
* Parse the specified Element and register any resulting BeanDefinitions with the BeanDefinitionRegistry that is embedded in the supplied ParserContext.
594
* @param element the element that is to be parsed into one or more BeanDefinitions
595
* @param parserContext the object encapsulating the current state of the parsing process
596
* @return the primary BeanDefinition resulting from the parsing of the supplied Element (can be null)
597
*/
598
protected abstract AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext);
599
600
/**
601
* Resolve the ID for the supplied BeanDefinition.
602
* @param element the element that the bean definition has been built from
603
* @param definition the bean definition to be registered
604
* @param parserContext the object encapsulating the current state of the parsing process
605
* @return the resolved id
606
* @throws BeanDefinitionStoreException if no unique name can be generated for the given bean definition
607
*/
608
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) throws BeanDefinitionStoreException;
609
610
/**
611
* Should an ID be generated instead of read from the passed in Element?
612
* @param element the element that the bean definition has been built from
613
* @return true if an ID should be generated instead of using element's "id" attribute value
614
*/
615
protected boolean shouldGenerateId();
616
617
/**
618
* Should an ID be generated instead if the passed in Element does not specify an "id" attribute explicitly?
619
* @param element the element that the bean definition has been built from
620
* @return true if an ID should be generated if no explicit id specified
621
*/
622
protected boolean shouldGenerateIdAsFallback();
623
624
/**
625
* Controls whether this parser is supposed to fire a BeanComponentDefinition event after parsing the bean definition.
626
* @return true in order to fire a component registration event after parsing the bean definition; false to suppress the registration event
627
*/
628
protected boolean shouldFireEvents();
629
630
/**
631
* Hook method called after the primary parsing of an Element but before the BeanDefinition has been decorated.
632
* @param beanDefinition the parsed (and possibly merged) bean definition being built
633
* @param element the element that was the source of the bean definition's metadata
634
* @param parserContext the object encapsulating the current state of the parsing process
635
*/
636
protected void postProcessComponentDefinition(AbstractBeanDefinition beanDefinition, Element element, ParserContext parserContext);
637
}
638
```
639
640
**Usage Examples:**
641
642
```java
643
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
644
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
645
import org.springframework.core.io.ClassPathResource;
646
import org.springframework.core.io.Resource;
647
648
// Basic XML configuration loading
649
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
650
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
651
652
// Load bean definitions from classpath
653
Resource resource = new ClassPathResource("applicationContext.xml");
654
int beanCount = reader.loadBeanDefinitions(resource);
655
656
// Configure validation mode
657
reader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_XSD);
658
reader.setNamespaceAware(true);
659
660
// Load multiple configuration files
661
reader.loadBeanDefinitions(
662
new ClassPathResource("beans.xml"),
663
new ClassPathResource("services.xml"),
664
new ClassPathResource("repositories.xml")
665
);
666
667
// Get configured beans
668
MyService service = factory.getBean("myService", MyService.class);
669
```
670
671
Example XML configuration file (`applicationContext.xml`):
672
673
```xml
674
<?xml version="1.0" encoding="UTF-8"?>
675
<beans xmlns="http://www.springframework.org/schema/beans"
676
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
677
xmlns:context="http://www.springframework.org/schema/context"
678
xsi:schemaLocation="
679
http://www.springframework.org/schema/beans
680
http://www.springframework.org/schema/beans/spring-beans.xsd
681
http://www.springframework.org/schema/context
682
http://www.springframework.org/schema/context/spring-context.xsd">
683
684
<!-- Simple bean definition -->
685
<bean id="dataSource" class="com.example.BasicDataSource">
686
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
687
<property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
688
<property name="username" value="user"/>
689
<property name="password" value="password"/>
690
</bean>
691
692
<!-- Bean with constructor arguments -->
693
<bean id="userService" class="com.example.UserService">
694
<constructor-arg ref="userRepository"/>
695
<constructor-arg value="30"/>
696
</bean>
697
698
<!-- Bean with factory method -->
699
<bean id="messageFactory" class="com.example.MessageFactory"
700
factory-method="createInstance"/>
701
702
<!-- Bean with init and destroy methods -->
703
<bean id="connectionPool" class="com.example.ConnectionPool"
704
init-method="initialize" destroy-method="cleanup">
705
<property name="maxConnections" value="100"/>
706
</bean>
707
708
<!-- Prototype scope bean -->
709
<bean id="shoppingCart" class="com.example.ShoppingCart" scope="prototype"/>
710
711
<!-- Lazy initialization -->
712
<bean id="expensiveResource" class="com.example.ExpensiveResource"
713
lazy-init="true"/>
714
715
<!-- Bean with depends-on -->
716
<bean id="cacheManager" class="com.example.CacheManager"
717
depends-on="dataSource,connectionPool"/>
718
719
<!-- Collection properties -->
720
<bean id="emailService" class="com.example.EmailService">
721
<property name="templates">
722
<map>
723
<entry key="welcome" value="templates/welcome.html"/>
724
<entry key="goodbye" value="templates/goodbye.html"/>
725
</map>
726
</property>
727
<property name="recipients">
728
<list>
729
<value>admin@example.com</value>
730
<value>support@example.com</value>
731
</list>
732
</property>
733
</bean>
734
735
<!-- Enable annotation-based configuration -->
736
<context:annotation-config/>
737
738
<!-- Component scanning -->
739
<context:component-scan base-package="com.example.services"/>
740
741
</beans>
742
```
743
744
### Entity Resolver Support
745
746
Support for resolving XML entities, DTDs, and schemas during XML parsing.
747
748
```java { .api }
749
/**
750
* EntityResolver implementation that delegates to a BeansDtdResolver and a PluggableSchemaResolver for DTDs and XML schemas, respectively.
751
*/
752
class DelegatingEntityResolver implements EntityResolver {
753
/** Suffix for DTD files. */
754
public static final String DTD_SUFFIX = ".dtd";
755
/** Suffix for schema definition files. */
756
public static final String XSD_SUFFIX = ".xsd";
757
758
/**
759
* Create a new DelegatingEntityResolver that delegates to a default BeansDtdResolver and a default PluggableSchemaResolver.
760
* @param classLoader the ClassLoader to use for loading (can be null to use the default ClassLoader)
761
*/
762
public DelegatingEntityResolver(ClassLoader classLoader);
763
764
/**
765
* Create a new DelegatingEntityResolver that delegates to the given EntityResolvers.
766
* @param dtdResolver the EntityResolver to use for DTDs
767
* @param schemaResolver the EntityResolver to use for XML schemas
768
*/
769
public DelegatingEntityResolver(EntityResolver dtdResolver, EntityResolver schemaResolver);
770
771
/**
772
* Resolve the entity: for DTDs, delegate to the dtdResolver; for schemas, delegate to the schemaResolver.
773
* @param publicId the public identifier of the external entity being referenced, or null if none was supplied
774
* @param systemId the system identifier of the external entity being referenced
775
* @return an InputSource object describing the new input source, or null to request that the parser open a regular URI connection to the system identifier
776
* @throws SAXException any SAX exception, possibly wrapping another exception
777
* @throws IOException a Java-specific IO exception, possibly the result of creating a new InputStream or Reader for the InputSource
778
*/
779
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException;
780
}
781
782
/**
783
* EntityResolver implementation for the Spring beans DTD, to load the DTD from the Spring class path (or JAR file).
784
*/
785
class BeansDtdResolver implements EntityResolver {
786
private static final String DTD_EXTENSION = ".dtd";
787
private static final String DTD_NAME = "spring-beans";
788
789
/**
790
* Resolve the entity: for the beans DTD, return a cached InputSource object; otherwise, return null.
791
* @param publicId the public identifier of the external entity being referenced, or null if none was supplied
792
* @param systemId the system identifier of the external entity being referenced
793
* @return an InputSource object describing the new input source, or null to request that the parser open a regular URI connection to the system identifier
794
* @throws IOException if the DTD cannot be loaded
795
*/
796
public InputSource resolveEntity(String publicId, String systemId) throws IOException;
797
}
798
799
/**
800
* EntityResolver implementation that attempts to resolve schema URLs into local classpath resources using a set of mappings files.
801
*/
802
class PluggableSchemaResolver implements EntityResolver {
803
/** The location of the mapping files. */
804
public static final String DEFAULT_SCHEMA_MAPPINGS_LOCATION = "META-INF/spring.schemas";
805
806
/**
807
* Create a new PluggableSchemaResolver that will attempt to resolve schema URL into local classpath resources using the default set of mappings.
808
* @param classLoader the ClassLoader to use for loading (can be null to use the default ClassLoader)
809
*/
810
public PluggableSchemaResolver(ClassLoader classLoader);
811
812
/**
813
* Create a new PluggableSchemaResolver using the supplied ClassLoader and schema mappings location.
814
* @param classLoader the ClassLoader to use for loading (can be null to use the default ClassLoader)
815
* @param schemaMappingsLocation the location of the file that defines schema mappings (must not be null)
816
*/
817
public PluggableSchemaResolver(ClassLoader classLoader, String schemaMappingsLocation);
818
819
/**
820
* Resolve the entity: for schema files, attempt to find a mapping in the mappings file and return a corresponding Resource from the classpath.
821
* @param publicId the public identifier of the external entity being referenced, or null if none was supplied
822
* @param systemId the system identifier of the external entity being referenced
823
* @return an InputSource object describing the new input source, or null to request that the parser open a regular URI connection to the system identifier
824
* @throws IOException if the schema cannot be loaded
825
*/
826
public InputSource resolveEntity(String publicId, String systemId) throws IOException;
827
}
828
```