Skip to content

Decouple XML parsing from bean registration in BeanDefinitionParsers [SPR-5102] #9775

Closed
@spring-projects-issues

Description

@spring-projects-issues

Chris Beams opened SPR-5102 and commented

The BeanDefinitionParser API specifies #parse(Element, ParserContext). This is fine, however, in most BeanDefinitionParser implementations (see ComponentScanBeanDefinitionParser, AnnotationDrivenBeanDefinitionParser) complex logic relating to which beans to register is tangled up with parsing the XML Element object passed in.

Ideally, we should decouple XML parsing from bean registration logic, probably through a simple delegation model.

The BeanDefinitionParser SPI (and all of our existing internal implementations' public interfaces) can remain the same. parse() will continue to take an Element and a ParserContext.

However, parse() should be limited to parsing the XML Element into a object specific to the metadata contained in that element (see below in open issues regarding naming of those objects).

Once parsing is complete, the BeanDefinitionParser should delegate to an object that understands how to read that now-abstract metadata and register bean definitions that are appropriate given its values. (naming: BeanDefinitionRegistrar?)

Open issues:

  1. What do we call the abstract representation of the metadata coming from the namespace elements (or annotations in the JavaConfig case)?

For example, when parsing <context:component-scan base-packages="com.acme, com.foo" annotation-config="false"/> it will be parsed into an object that looks something like:

public class XXX {
private String[] basePackages;
private boolean annotationConfig;

public void setBasePackages(String[] basePackages) {
    this.basePackages = basePackages;
}

public String[] getBasePackages() {
    return basePackages;
}

// other accessors ...

}

The question is, what should class XXX above be called? What, fundamentally, is a namespace representing with regard to the Spring configuration model as a whole? Consider the following - today in Spring XML we have what are simply referred to as 'namespaces':

<context:component-scan base-packages="...", annotation-config="false"/>

JavaConfig, on the other hand, expresses this same metadata through a type-level annotation:

@ComponentScan(value="...", annotationConfig=false);

Same metadata, different vehicles for its transmission.

In the abstract, then, what is this metadata? We could call XXX any of the following:

ComponentScanDescriptor
ComponentScanDeclaration
ComponentScanPlugin
ComponentScanModule
ComponentScanExtension

In some ways, I like 'descriptor': it connotes that the object is little more than a data holder, a struct if you will. It is not expressive, however, about its role or purpose in the larger model. Currently JavaConfig is referring to these things in the abstract as 'ConfigurationPlugin' instances, where ConfigurationPlugin is an interface.

  1. ParserContext

We will also need to consider ParserContext, and any ties it has to XML. JavaConfig will also need to make use of ParserContext (or something like it) in order to communicate bean/component registrations to Spring IDE.


Issue Links:

Metadata

Metadata

Assignees

No one assigned

    Labels

    in: coreIssues in core modules (aop, beans, core, context, expression)type: taskA general task

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions