Appendix C. XML Schema-based configuration

C.1 Introduction

This appendix details the XML Schema-based configuration introduced in Spring 2.0 and enhanced and extended in Spring 2.5 and 3.0.

DTD support?

Authoring Spring configuration files using the older DTD style
is still fully supported.

Nothing will break if you forego the use of the new XML Schema-based
approach to authoring Spring XML configuration files. All that you lose
out on is the opportunity to have more succinct and clearer configuration.
Regardless of whether the XML configuration is DTD- or Schema-based, in the end
it all boils down to the same object model in the container (namely one or
more BeanDefinition instances).

The central motivation for moving to XML Schema based configuration files was
to make Spring XML configuration easier. The 'classic'<bean/>-based approach is good, but its generic-nature comes
with a price in terms of configuration overhead.

From the Spring IoC containers point-of-view, everything
is a bean. That's great news for the Spring IoC container, because if everything is
a bean then everything can be treated in the exact same fashion. The same, however,
is not true from a developer's point-of-view. The objects defined in a Spring
XML configuration file are not all generic, vanilla beans. Usually, each bean requires
some degree of specific configuration.

Spring 2.0's new XML Schema-based configuration addresses this issue.
The <bean/> element is still present, and if you
wanted to, you could continue to write the exact same
style of Spring XML configuration using only <bean/>
elements. The new XML Schema-based configuration does, however, make
Spring XML configuration files substantially clearer to read. In addition, it allows
you to express the intent of a bean definition.

The key thing to remember is that the new custom tags work best for infrastructure
or integration beans: for example, AOP, collections, transactions, integration with
3rd-party frameworks such as Mule, etc., while the existing bean tags are best suited to
application-specific beans, such as DAOs, service layer objects, validators, etc.

The examples included below will hopefully convince you that the inclusion
of XML Schema support in Spring 2.0 was a good idea. The reception in the community
has been encouraging; also, please note the fact that this new configuration mechanism
is totally customisable and extensible. This means you can write your own domain-specific
configuration tags that would better represent your application's domain; the process
involved in doing so is covered in the appendix entitled Appendix D, Extensible XML authoring.

C.2 XML Schema-based configuration

C.2.1 Referencing the schemas

To switch over from the DTD-style to the new XML Schema-style, you need
to make the following change.

The 'xsi:schemaLocation' fragment is not actually required,
but can be included to reference a local copy of a schema (which can be useful
during development).

The above Spring XML configuration fragment is boilerplate that you can copy and paste
(!) and then plug <bean/> definitions into like you have always
done. However, the entire point of switching over is to
take advantage of the new Spring 2.0 XML tags since they make configuration easier. The
section entitled Section C.2.2, “The util schema” demonstrates how you can
start immediately by using some of the more common utility tags.

The rest of this chapter is devoted to showing examples of the new Spring XML Schema
based configuration, with at least one example for every new tag. The format follows
a before and after style, with a before snippet of XML showing
the old (but still 100% legal and supported) style, followed immediately
by an after example showing the equivalent in the new XML Schema-based
style.

C.2.2 The util schema

First up is coverage of the util tags. As the name
implies, the util tags deal with common, utility
configuration issues, such as configuring collections, referencing constants,
and suchlike.

To use the tags in the util schema, you need to have
the following preamble at the top of your Spring XML configuration file;
the bold text in the snippet below references the correct schema so that
the tags in the util namespace are available to you.

The above configuration uses a Spring FactoryBean
implementation, the FieldRetrievingFactoryBean, to
set the value of the 'isolation' property on a bean
to the value of the 'java.sql.Connection.TRANSACTION_SERIALIZABLE'
constant. This is all well and good, but it is a tad verbose and (unneccessarily)
exposes Spring's internal plumbing to the end user.

The following XML Schema-based version is more concise
and clearly expresses the developer's intent ('inject this constant
value'), and it just reads better.

Setting a bean property or constructor arg from a field value

FieldRetrievingFactoryBean
is a FactoryBean which retrieves a
static or non-static field value. It is typically
used for retrieving publicstaticfinal constants, which may then be used to set a
property value or constructor arg for another bean.

Find below an example which shows how a static field is exposed, by
using the staticField
property:

This does mean that there is no longer any choice in what the bean id is (so
any other bean that refers to it will also have to use this longer name),
but this form is very concise to define, and very convenient to use as an
inner bean since the id doesn't have to be specified for the bean
reference:

It is also possible to access a non-static (instance) field of another bean,
as described in the API documentation for the
FieldRetrievingFactoryBean
class.

Injecting enum values into beans as either property or constructor arguments is very
easy to do in Spring, in that you don't actually have to do
anything or know anything about the Spring internals (or even about classes such
as the FieldRetrievingFactoryBean). Let's look at an example
to see how easy injecting an enum value is; consider this JDK 5 enum:

This works for classic type-safe emulated enums (on JDK 1.4 and JDK 1.3) as well;
Spring will automatically attempt to match the string property value to a constant
on the enum class.

C.2.2.2 <util:property-path/>

Before...

<!-- target bean to be referenced by name -->
<beanid="testBean"class="org.springframework.beans.TestBean"scope="prototype">
<propertyname="age"value="10"/>
<propertyname="spouse">
<beanclass="org.springframework.beans.TestBean">
<propertyname="age"value="11"/>
</bean>
</property>
</bean>
<!-- will result in 10, which is the value of property 'age' of bean 'testBean' -->
<beanid="testBean.age"class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>

The above configuration uses a Spring FactoryBean
implementation, the PropertyPathFactoryBean, to
create a bean (of type int) called
'testBean.age' that has a value equal to the 'age'
property of the 'testBean' bean.

After...

<!-- target bean to be referenced by name -->
<beanid="testBean"class="org.springframework.beans.TestBean"scope="prototype">
<propertyname="age"value="10"/>
<propertyname="spouse">
<beanclass="org.springframework.beans.TestBean">
<propertyname="age"value="11"/>
</bean>
</property>
</bean>
<!-- will result in 10, which is the value of property 'age' of bean 'testBean' -->
<util:property-pathid="name"path="testBean.age"/>

The value of the 'path' attribute of the
<property-path/> tag follows the form 'beanName.beanProperty'.

Using <util:property-path/> to set a bean property or constructor-argument

PropertyPathFactoryBean is a
FactoryBean that evaluates a property path on a given
target object. The target object can be specified directly or via a bean
name. This value may then be used in another bean definition as a property
value or constructor argument.

Here's an example where a path is used against another bean, by name:

// target bean to be referenced by name
<beanid="person"class="org.springframework.beans.TestBean"scope="prototype">
<propertyname="age"value="10"/>
<propertyname="spouse">
<beanclass="org.springframework.beans.TestBean">
<propertyname="age"value="11"/>
</bean>
</property>
</bean>
// will result in 11, which is the value of property 'spouse.age' of bean 'person'
<beanid="theAge"class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
<propertyname="targetBeanName"value="person"/>
<propertyname="propertyPath"value="spouse.age"/>
</bean>

In this example, a path is evaluated against an inner bean:

<!-- will result in 12, which is the value of property 'age' of the inner bean -->
<beanid="theAge"class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
<propertyname="targetObject">
<beanclass="org.springframework.beans.TestBean">
<propertyname="age"value="12"/>
</bean>
</property>
<propertyname="propertyPath"value="age"/>
</bean>

There is also a shortcut form, where the bean name is the property path.

<!-- will result in 10, which is the value of property 'age' of bean 'person' -->
<beanid="person.age"class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>

This form does mean that there is no choice in the name of the bean.
Any reference to it will also have to use the same id, which is the path.
Of course, if used as an inner bean, there is no need to refer to it at
all:

You can also explicitly control the exact type of List
that will be instantiated and populated via the use of the 'list-class'
attribute on the <util:list/> element. For example, if we
really need a java.util.LinkedList to be instantiated, we could
use the following configuration:

You can also explicitly control the exact type of Map
that will be instantiated and populated via the use of the 'map-class'
attribute on the <util:map/> element. For example, if we
really need a java.util.TreeMap to be instantiated, we could
use the following configuration:

You can also explicitly control the exact type of Set
that will be instantiated and populated via the use of the 'set-class'
attribute on the <util:set/> element. For example, if we
really need a java.util.TreeSet to be instantiated, we could
use the following configuration:

If no 'set-class' attribute is supplied, a
Set implementation will be chosen by the container.

Finally, you can also control the merging behavior using the
'merge' attribute of the <util:set/>
element; collection merging is described in more detail in
the section called “Collection merging”.

C.2.3 The jee schema

The jee tags deal with JEE (Java Enterprise Edition)-related
configuration issues, such as looking up a JNDI object and defining EJB references.

To use the tags in the jee schema, you need to have
the following preamble at the top of your Spring XML configuration file;
the bold text in the following snippet references the correct schema so that
the tags in the jee namespace are available to you.

C.2.4 The lang schema

The lang tags deal with exposing objects that have been
written in a dynamic language such as JRuby or Groovy as beans in the Spring
container.

These tags (and the dynamic language support) are comprehensively covered
in the chapter entitled Chapter 26, Dynamic language support. Please do consult that
chapter for full details on this support and the lang tags
themselves.

In the interest of completeness, to use the tags in the lang
schema, you need to have the following preamble at the top of your Spring XML
configuration file; the bold text in the following snippet references the
correct schema so that the tags in the lang namespace are
available to you.

In the interest of completeness, to use the tags in the jms
schema, you need to have the following preamble at the top of your Spring XML
configuration file; the bold text in the following snippet references the
correct schema so that the tags in the jms namespace are
available to you.

C.2.6 The tx (transaction) schema

The tx tags deal with configuring all of those
beans in Spring's comprehensive support for transactions. These tags are
covered in the chapter entitled Chapter 10, Transaction Management.

Tip

You are strongly encouraged to look at the
'spring-tx-3.0.xsd' file that ships with the Spring
distribution. This file is (of course), the XML Schema for Spring's
transaction configuration, and covers all of the various tags in the
tx namespace, including attribute defaults and
suchlike. This file is documented inline, and thus the information is
not repeated here in the interests of adhering to the DRY (Don't Repeat
Yourself) principle.

In the interest of completeness, to use the tags in the tx
schema, you need to have the following preamble at the top of your Spring XML
configuration file; the bold text in the following snippet references the
correct schema so that the tags in the tx namespace are
available to you.

Often when using the tags in the tx namespace you will also be using
the tags from the aop namespace (since the declarative transaction support in Spring is implemented using
AOP). The above XML snippet contains the relevant lines needed to reference the aop schema
so that the tags in the aop namespace are available to you.

C.2.7 The aop schema

The aop tags deal with configuring all things
AOP in Spring: this includes Spring's own proxy-based AOP framework and Spring's
integration with the AspectJ AOP framework. These tags are
comprehensively covered in the chapter entitled Chapter 7, Aspect Oriented Programming with Spring.

In the interest of completeness, to use the tags in the aop
schema, you need to have the following preamble at the top of your Spring XML
configuration file; the bold text in the following snippet references the
correct schema so that the tags in the aop namespace are
available to you.

C.2.8 The context schema

The context tags deal with ApplicationContext
configuration that relates to plumbing - that is, not usually beans that are important to an end-user
but rather beans that do a lot of grunt work in Spring, such as BeanfactoryPostProcessors.
The following snippet references the correct schema so that the tags in the context
namespace are available to you.

C.2.8.1 <property-placeholder/>

This element activates the replacement of ${...} placeholders, resolved
against the specified properties file (as a Spring resource location).
This element is a convenience mechanism that sets up a
PropertyPlaceholderConfigurer
for you; if you need more control over the PropertyPlaceholderConfigurer, just
define one yourself explicitly.

C.2.8.2 <annotation-config/>

Activates the Spring infrastructure for various annotations to be detected in bean classes:
Spring's @Required
and @Autowired, as well as
JSR 250's @PostConstruct, @PreDestroy and
@Resource (if available), and JPA's
@PersistenceContext and @PersistenceUnit
(if available). Alternatively, you can choose to activate the individual
BeanPostProcessors for those annotations explictly.

C.2.8.6 <mbean-export/>

C.2.9 The tool schema

The tool tags are for use when you want to add
tooling-specific metadata to your custom configuration elements. This metadata
can then be consumed by tools that are aware of this metadata, and the tools can
then do pretty much whatever they want with it (validation, etc.).

The tool tags are not documented in this release of
Spring as they are currently undergoing review. If you are a third party tool
vendor and you would like to contribute to this review process, then do mail
the Spring mailing list. The currently supported tool
tags can be found in the file 'spring-tool-3.0.xsd' in the
'src/org/springframework/beans/factory/xml' directory of the
Spring source distribution.

C.2.10 The beans schema

Last but not least we have the tags in the beans schema.
These are the same tags that have been in Spring since the very dawn of the framework.
Examples of the various tags in the beans schema are not shown here
because they are quite comprehensively covered in Section 3.4.2, “Dependencies and configuration in detail”
(and indeed in that entire chapter).

One thing that is new to the beans tags themselves in Spring 2.0 is the idea
of arbitrary bean metadata. In Spring 2.0 it is now possible to add zero or more
key / value pairs to <bean/> XML definitions. What, if
anything, is done with this extra metadata is totally up to your own custom logic (and
so is typically only of use if you are writing your own custom tags as described in
the appendix entitled Appendix D, Extensible XML authoring).

Find below an example of the <meta/> tag in the context
of a surrounding <bean/> (please note that without any logic
to interpret it the metadata is effectively useless as-is).

In the case of the above example, you would assume that there is some
logic that will consume the bean definition and set up some caching infrastructure
using the supplied metadata.

C.3 Setting up your IDE

This final section documents the steps involved in setting up a number of
popular Java IDEs to effect the easier editing of Spring's XML Schema-based
configuration files. If your favourite Java IDE or editor is not included in the
list of documented IDEs, then please do
raise an issue
and an example with your favorite IDE/editor may be included
in the next release.

C.3.1 Setting up Eclipse

The following steps illustrate setting up
Eclipse to be XSD-aware.
The assumption in the following steps is that you already have an Eclipse
project open (either a brand new project or an already existing one).

Note

The following steps were created using Eclipse 3.2.
The setup will probably be the same (or similar) on an earlier or later
version of Eclipse.

Step One

Create a new XML file. You can name this file whatever you want. In the
example below, the file is named 'context.xml'.
Copy and paste the following text into the file so that it matches the screenshot.

As can be seen in the above screenshot (unless you have a customised
version of Eclipse with the correct plugins) the XML file will be treated
as plain text. There is no XML editing support out of the box in Eclipse,
and as such there is not even any syntax highlighting of elements and attributes.
To address this, you will have to install an XML editor plugin for Eclipse...

Patches showing how to configure an Eclipse XML editor are
welcomed. Any such contributions are best submitted as patches via
the Spring Framework
JIRA Issue Tracker
and may be featured in the next release.

Unfortunately, precisely because there is no standard XML editor for Eclipse,
there are (bar the one below) no further steps showing you how to configure XML
Schema support in Eclipse... each XML editor plugin would require its very own
dedicated section, and this is Spring reference documentation,
not Eclipse XML editor documentation. You will have to read the documentation that
comes with your XML editor plugin (good luck there) and figure it out for yourself.

Spring IDE

There is a dedicated Spring Framework plugin for Eclipse called
Spring IDE and it is pretty darn cool. (There's a
considered and non-biased opinion for you!) This plugin makes using Spring even easier, and it has more
than just support for the core Spring Framework... Spring Web Flow is supported too. Details of how to
install Spring IDE can be found on the
Spring IDE installation page.

Web Tools Platform (WTP) for Eclipse

If you are using the Web Tools Platform (WTP) for Eclipse, you don't need to
do anything other than open a Spring XML configuration file using the WTP platform's
XML editor. As can be seen in the screenshot below, you immediately get some slick
IDE-level support for autocompleting tags and suchlike.

C.3.2 Setting up IntelliJ IDEA

The following steps illustrate setting up the
IntelliJ IDEA IDE to be XSD-aware.
The assumption in the following steps is that you already have an IDEA project
open (either a brand new project or an already existing one).

Repeat as required for setting up IDEA to reference the other Spring XSD files.

Step One

Create a new XML file (you can name this file whatever you want). In the
example below, the file is named 'context.xml'. Copy and paste
the following text into the file so that it matches the screenshot.

As can be seen in the above screenshot, the XML file has a number
of nasty red contextual error markers. To rectify this, IDEA has to be
made aware of the location of the referenced XSD namespace(s).

To do this, simply position the cursor over the squiggly red
area (see the screenshot below); then press the Alt+Enter keystroke combination, and press the Enter key again when the popup becomes active to fetch the external
resource.

Step Three

If the external resource could not be fetched (maybe no active Internet
connection is available), you can manually configure the resource to
reference a local copy of the XSD file. Simply open up the 'Settings' dialog
(using the Ctrl+A+S keystroke combination or via the 'File|Settings' menu),
and click on the 'Resources' button.

Step Four

As can be seen in the following screenshot, this will bring up a dialog
that allows you to add an explicit reference to a local copy of the
util schema file. (You can find all of the various Spring
XSD files in the 'src' directory of the Spring distribution.)

Step Five

Clicking the 'Add' button will bring up another dialog
that allows you to explicitly to associate a namespace URI with the path to the
relevant XSD file. As can be seen in the following screenshot, the
'http://www.springframework.org/schema/util' namespace
is being associated with the file resource
'C:\bench\spring\src\org\springframework\beans\factory\xml\spring-util-3.0.xsd'.

Step Six

Exiting out of the nested dialogs by clicking the 'OK' button
will then bring back the main editing window, and as can be seen in the
following screenshot, the contextual error markers have disappeared; typing
the '<' character into the editing window now also
brings up a handy dropdown box that contains all of the imported tags from
the util namespace.

C.3.3 Integration issues

This final section details integration issues that may arise when you switch over
to using the above XSD-style for Spring 2.0 and later configuration.

This section is quite small at the moment (and hopefully it will stay that way).
It has been included in the Spring documentation as a convenience to Spring users
so that if you encounter an issue when switching over to the XSD-style in some
specific environment you can refer to this section for the authoritative answer.

C.3.3.1 XML parsing errors in the Resin v.3 application server

If you are using the XSD-style for Spring 2.0 XML configuration
and deploying to v.3 of Caucho's Resin application server, you will need
to set some configuration options prior to startup so that an XSD-aware
parser is available to Spring.