This section of the reference documentation details the XML Schema based configuration introduced in Spring 2.0.
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; something that is not covered in this section (at least not right now) is 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.
To switch over from the DTD-style to the new XML Schema-style, you need to make the following change.
<!-- DTD-style --> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!-- <bean/> definitions here --> </beans>
The equivalent file in the XML Schema-style would be...
<!-- XML Schema-style --> <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- <bean/> definitions here --> </beans>
Note | |
---|---|
The 'xsi:schemaLocation' fragment is not actually required, but can be specified to refer to a local copy of a schema (which can be useful during development). |
The above Spring XML configuration fragment is pretty much boilerplate; you can simply use this and continue to write <bean/> definitions 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 A.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.
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 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 emboldened text in the snippet below references the correct schema so that the tags in the util namespace are available to you.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <!-- <bean/> definitions here --> </beans>
Before...
<bean id="..." class="..."> <property name="isolation"> <bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" /> </property> </bean>
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.
<bean id="..." class="..."> <property name="isolation"> <util:constant static-field="java.sql.Connection.TRANSACTION_SERIALIZABLE"/> </property> </bean>
FieldRetrievingFactoryBean is a FactoryBean which retrieves a static or non-static field value. It is typically used for retrieving public static final 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:
<bean id="myField" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"> <property name="staticField"> <value>java.sql.Connection.TRANSACTION_SERIALIZABLE</value> </property> </bean>
There is also a convenience usage form where the static field is specified as a bean name:
<bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"/>
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:
<bean id="..." class="..."> <property name="isolation"> <bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" /> </property> </bean>
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 a cinch in Spring, in that one doesn'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:
package javax.persistence; public enum PersistenceContextType { TRANSACTION, EXTENDED }
Now consider a setter of type PersistenceContextType:
package example; public class Client { private PersistenceContextType persistenceContextType; public void setPersistenceContextType(PersistenceContextType type) { this.persistenceContextType = type; } }
.. and the corresponding bean definition:
<bean class="example.Client"> <property name="persistenceContextType" value="TRANSACTION" /> </bean>
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.
Before...
<!-- target bean to be referenced by name --> <bean id="testBean" class="org.springframework.beans.TestBean" singleton="false"> <property name="age" value="10"/> <property name="spouse"> <bean class="org.springframework.beans.TestBean"> <property name="age" value="11"/> </bean> </property> </bean> <!-- will result in 10, which is the value of property 'age' of bean 'testBean' --> <bean id="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 --> <bean id="testBean" class="org.springframework.beans.TestBean" singleton="false"> <property name="age" value="10"/> <property name="spouse"> <bean class="org.springframework.beans.TestBean"> <property name="age" value="11"/> </bean> </property> </bean> <!-- will result in 10, which is the value of property 'age' of bean 'testBean' --> <util:property-path id="name" path="testBean.age"/>
The value of the 'path' attribute of the <property-path/> tag follows the form 'beanName.beanProperty'.
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
<bean id="person" class="org.springframework.beans.TestBean" singleton="false">
<property name="age"><value>10</value></property>
<property name="spouse">
<bean class="org.springframework.beans.TestBean">
<property name="age"><value>11</value></property>
</bean>
</property>
</bean>
// will result in 11, which is the value of property 'spouse.age' of bean 'person'
<bean id="theAge"
class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
<property name="targetBeanName" value="person"/>
<property name="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 -->
<bean id="theAge"
class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
<property name="targetObject">
<bean class="org.springframework.beans.TestBean">
<property name="age" value="12"/>
</bean>
</property>
<property name="propertyPath"><value>age</value></property>
</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' -->
<bean id="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:
<bean id="..." class="..."> <property name="age"> <bean id="person.age" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/> </property> </bean>
The result type may be specifically set in the actual definition. This is not necessary for most use cases, but can be of use for some. Please see the Javadocs for more info on this feature.
Before...
<!-- creates a java.util.Properties instance with values loaded from the supplied location -->
<bean id="jdbcConfiguration" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:com/foo/jdbc-production.properties"/>
</bean>
The above configuration uses a Spring FactoryBean implementation, the PropertiesFactoryBean, to instantiate a java.util.Properties instance with values loaded from the supplied Resource location).
After...
<!-- creates a java.util.Properties instance with values loaded from the supplied location -->
<util:properties id="jdbcConfiguration" location="classpath:com/foo/jdbc-production.properties"/>
Before...
<!-- creates a java.util.List instance with values loaded from the supplied 'sourceList' --> <bean id="emails" class="org.springframework.beans.factory.config.ListFactoryBean"> <property name="sourceList"> <list> <value>[email protected]</value> <value>[email protected]</value> <value>[email protected]</value> <value>[email protected]</value> </list> </property> </bean>
The above configuration uses a Spring FactoryBean implementation, the ListFactoryBean, to create a java.util.List instance initialized with values taken from the supplied 'sourceList'.
After...
<!-- creates a java.util.List instance with values loaded from the supplied 'sourceList' --> <util:list id="emails"> <value>[email protected]</value> <value>[email protected]</value> <value>[email protected]</value> <value>[email protected]</value> </util:list>
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:
<util:list id="emails" list-class="java.util.LinkedList"> <value>[email protected]</value> <value>[email protected]</value> <value>[email protected]</value> <value>d'[email protected]</value> </util:list>
If no 'list-class' attribute is supplied, a List implementation will be chosen by the container.
Finally, you can also control the merging behavior using the 'merge' attribute of the <util:list/> element; collection merging is described in more detail in the section entitled Section 3.3.3.4.1, “集合合并”
Before...
<!-- creates a java.util.Map instance with values loaded from the supplied 'sourceMap' --> <bean id="emails" class="org.springframework.beans.factory.config.MapFactoryBean"> <property name="sourceMap"> <map> <entry key="pechorin" value="[email protected]"/> <entry key="raskolnikov" value="[email protected]"/> <entry key="stavrogin" value="[email protected]"/> <entry key="porfiry" value="[email protected]"/> </list> </property> </bean>
The above configuration uses a Spring FactoryBean implementation, the MapFactoryBean, to create a java.util.Map instance initialized with key-value pairs taken from the supplied 'sourceMap'.
After...
<!-- creates a java.util.Map instance with values loaded from the supplied 'sourceMap' --> <util:map id="emails"> <entry key="pechorin" value="[email protected]"/> <entry key="raskolnikov" value="[email protected]"/> <entry key="stavrogin" value="[email protected]"/> <entry key="porfiry" value="[email protected]"/> </util:map>
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:
<util:map id="emails" map-type="java.util.TreeMap"> <entry key="pechorin" value="[email protected]"/> <entry key="raskolnikov" value="[email protected]"/> <entry key="stavrogin" value="[email protected]"/> <entry key="porfiry" value="[email protected]"/> </util:map>
If no 'map-class' attribute is supplied, a Map implementation will be chosen by the container.
Finally, you can also control the merging behavior using the 'merge' attribute of the <util:map/> element; collection merging is described in more detail in the section entitled Section 3.3.3.4.1, “集合合并”
Before...
<!-- creates a java.util.Set instance with values loaded from the supplied 'sourceSet' --> <bean id="emails" class="org.springframework.beans.factory.config.SetFactoryBean"> <property name="sourceSet"> <set> <value>[email protected]</value> <value>[email protected]</value> <value>[email protected]</value> <value>[email protected]</value> </set> </property> </bean>
The above configuration uses a Spring FactoryBean implementation, the SetFactoryBean, to create a java.util.Set instance initialized with values taken from the supplied 'sourceSet'.
After...
<!-- creates a java.util.Set instance with values loaded from the supplied 'sourceSet' --> <util:set id="emails"> <value>[email protected]</value> <value>[email protected]</value> <value>[email protected]</value> <value>[email protected]</value> </util:set>
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:
<util:set id="emails" set-class="java.util.TreeSet"> <value>[email protected]</value> <value>[email protected]</value> <value>[email protected]</value> <value>[email protected]</value> </util:set>
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 entitled Section 3.3.3.4.1, “集合合并”
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 emboldened text in the following snippet references the correct schema so that the tags in the jee namespace are available to you.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd"> <!-- <bean/> definitions here --> </beans>
Before...
<bean id="simple" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="jdbc/MyDataSource"/> </bean>
After...
<jee:jndi-lookup id="simple" jndi-name="jdbc/MyDataSource"/>
Before...
<bean id="simple" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="jdbc/MyDataSource"/> <property name="jndiEnvironment"> <props> <prop key="foo">bar</prop> </props> </property> </bean>
After...
<jee:jndi-lookup id="simple" jndi-name="jdbc/MyDataSource"> <jee:environment>foo=bar</jee:environment> </jee:jndi-lookup>
Before...
<bean id="simple" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="jdbc/MyDataSource"/> <property name="jndiEnvironment"> <props> <prop key="foo">bar</prop> <prop key="ping">pong</prop> </props> </property> </bean>
After...
<jee:jndi-lookup id="simple" jndi-name="jdbc/MyDataSource">
<!-- newline-separated, key-value pairs for the environment (standard Properties format) -->
<jee:environment>
foo=bar
ping=pong
</jee:environment>
</jee:jndi-lookup>
Before...
<bean id="simple" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="jdbc/MyDataSource"/> <property name="cache" value="true"/> <property name="resourceRef" value="true"/> <property name="lookupOnStartup" value="false"/> <property name="expectedType" value="com.myapp.DefaultFoo"/> <property name="proxyInterface" value="com.myapp.Foo"/> </bean>
After...
<jee:jndi-lookup id="simple" jndi-name="jdbc/MyDataSource" cache="true" resource-ref="true" lookup-on-startup="false" expected-type="com.myapp.DefaultFoo" proxy-interface="com.myapp.Foo"/>
The <jee:local-slsb/> tag configures a reference to an EJB Stateless SessionBean.
Before...
<bean id="simple" class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean"> <property name="jndiName" value="ejb/RentalServiceBean"/> <property name="businessInterface" value="com.foo.service.RentalService"/> </bean>
After...
<jee:local-slsb id="simpleSlsb" jndi-name="ejb/RentalServiceBean" business-interface="com.foo.service.RentalService"/>
<bean id="complexLocalEjb" class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean"> <property name="jndiName" value="ejb/RentalServiceBean"/> <property name="businessInterface" value="com.foo.service.RentalService"/> <property name="cacheHome" value="true"/> <property name="lookupHomeOnStartup" value="true"/> <property name="resourceRef" value="true"/> </bean>
After...
<jee:local-slsb id="complexLocalEjb" jndi-name="ejb/RentalServiceBean" business-interface="com.foo.service.RentalService" cache-home="true" lookup-home-on-startup="true" resource-ref="true">
The <jee:remote-slsb/> tag configures a reference to a remote EJB Stateless SessionBean.
Before...
<bean id="complexRemoteEjb" class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean"> <property name="jndiName" value="ejb/MyRemoteBean"/> <property name="businessInterface" value="com.foo.service.RentalService"/> <property name="cacheHome" value="true"/> <property name="lookupHomeOnStartup" value="true"/> <property name="resourceRef" value="true"/> <property name="homeInterface" value="com.foo.service.RentalService"/> <property name="refreshHomeOnConnectFailure" value="true"/> </bean>
After...
<jee:remote-slsb id="complexRemoteEjb" jndi-name="ejb/MyRemoteBean" business-interface="com.foo.service.RentalService" cache-home="true" lookup-home-on-startup="true" resource-ref="true" home-interface="com.foo.service.RentalService" refresh-home-on-connect-failure="true">
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 24, 动态语言支持. 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 emboldened text in the following snippet references the correct schema so that the tags in the lang namespace are available to you.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:lang="http://www.springframework.org/schema/lang" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd"> <!-- <bean/> definitions here --> </beans>
The tx tags deal with configuring all of those beans in Spring's comprehensive support for transactions. These tags are comprehensively covered in the chapter entitled Chapter 9, 事务管理.
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 emboldened text in the following snippet references the correct schema so that the tags in the tx namespace are available to you.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- <bean/> definitions here --> </beans>
Note | |
---|---|
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. |
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 6, 使用Spring进行面向切面编程(AOP).
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 emboldened text in the following snippet references the correct schema so that the tags in the aop namespace are available to you.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- <bean/> definitions here --> </beans>
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.xsd' in the 'src/org/springframework/beans/factory/xml' directory of the Spring source distribution.
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 on the Spring Framework JIRA Issue Tracker and an example with the IDE may may be featured in the next release.
Procedure A.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 attendant screenshot.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> </beans>
Step Two
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...
Table A.1. Eclipse XML editors
XML Editor | Link |
---|---|
The Eclipse Web Tools Platform (WTP) | http://www.eclipse.org/webtools/ |
A list of Eclipse XML plugins | http://eclipse-plugins.2y.net/eclipse/plugins.jsp?category=XML |
Unfortunately, precisely because there is no standard XML editor for Eclipse, there are 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. (The author is not trying to be cavalier, it's just that writing step-by-step setups for loads of Eclipse XML editor plugins would probably not be worth the effort precisely because there is no standard and there are so many different editors.)
Having said that...
Step Three
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. The moral of this story is... download and install the WTP, because (quite simply, and to paraphrase one of the Spring-WebFlow developers)... “[WTP] rocks!”
Procedure A.2. Setting up IntelliJ IDEA
The following steps illustrate how setting up IntelliJ IDEA to be XSD-aware. It is very simple to do so.
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 attendant screenshot.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> </beans>
Step Two
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 attendant 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.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.
This final section details integration issues that may arise when you switch over to using the above XSD-style for Spring 2.0 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.
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.
Please do consult the following resource on the Caucho Resin website for more information.