34.2.1Referencing the schemas
To switch over from the DTD-style to the new XML Schema-style,you need to make the following change.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
</beans>
The equivalent file in the XML Schema-style would be…
<?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">
|
The'xsi:schemaLocation'@H_502_34@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/>@H_502_34@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 entitledSection34.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 abeforesnippet of XML showing the old (but still 100% legal and supported) style,followed immediately by anafterexample showing the equivalent in the new XML Schema-based style.
First up is coverage of theutil@H_502_34@tags. As the name implies,theutil@H_502_34@tags deal with common,utilityconfiguration issues,such as configuring collections,referencing constants,and suchlike.
To use the tags in theutil@H_502_34@schema,you need to have the following preamble at the top of your Spring XML configuration file; the text in the snippet below references the correct schema so that the tags in theutil@H_502_34@namespace are available to you.
"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">
Before…
<bean id="..." class="...">
<property name="isolation">
"java.sql.Connection.TRANSACTION_SERIALIZABLE"
"org.springframework.beans.factory.config.FieldRetrievingfactorybean" />
</property>
</bean>
The above configuration uses a Springfactorybean@H_502_34@implementation,242)">FieldRetrievingfactorybean@H_502_34@,to set the value of theisolation@H_502_34@property on a bean to the value of thejava.sql.Connection.TRANSACTION_SERIALIZABLE@H_502_34@constant. This is all well and good,but it is a tad verbose and (unnecessarily) 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.
<util:constant static-field="java.sql.Connection.TRANSACTION_SERIALIZABLE"/>
</bean>
Setting a bean property or constructor arg from a field value
FieldRetrievingFactoryBean
is afactorybean@H_502_34@which retrieves astatic@H_502_34@or non-static field value. It is typically used for retrievingpublic@H_502_34@static@H_502_34@final@H_502_34@constants,which may then be used to set a property value or constructor arg for another bean.
Find below an example which shows how astatic@H_502_34@field is exposed,by using thestaticField
property:
"myField"
"staticField" value=/>
</bean>
There is also a convenience usage form where thestatic@H_502_34@field is specified as the bean name:
"java.sql.Connection.TRANSACTION_SERIALIZABLE"
/>
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>
It is also possible to access a non-static (instance) field of another bean,as described in the API documentation for theFieldRetrievingFactoryBeanclass.
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 todoanything or know anything about the Spring internals (or even about classes such as theFieldRetrievingfactorybean@H_502_34@). 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 typePersistenceContextType@H_502_34@:
package example;
public class Client {
private PersistenceContextType persistenceContextType;
void setPersistenceContextType(PersistenceContextType type) {
this.persistenceContextType = type;
}
}
- and the corresponding bean definition:
"example.Client""persistenceContextType" "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…
"testBean" "org.springframework.beans.TestBean" scope="prototype""age" "10""spouse""org.springframework.beans.TestBean">
"11"/>
</bean>
</bean>
age of bean testBean -->
"testBean.age" "org.springframework.beans.factory.config.PropertyPathfactorybean"/>
The above configuration uses a SpringPropertyPathfactorybean@H_502_34@,to create a bean (of typeint@H_502_34@) calledtestBean.age@H_502_34@that has a value equal to theage@H_502_34@property of thetestBean@H_502_34@bean.
After…
<util:property-path "name" path="testBean.age"/>
The value of thepath@H_502_34@attribute of the<property-path/>@H_502_34@tag follows the formbeanName.beanProperty@H_502_34@.
Using <util:property-path/> to set a bean property or constructor-argument
PropertyPathfactorybean@H_502_34@is afactorybean@H_502_34@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
"person" </bean>
// will result in 11,which is the value of property spouse.age of bean person
"theAge"
"targetBeanName" "person""propertyPath" "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 -->
"targetObject""12"</property>
"age"</bean>
There is also a shortcut form,where the bean name is the property path.
age of bean person -->
"person.age"
/>
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:
"person.age"
</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 -->
"jdbcConfiguration" "org.springframework.beans.factory.config.Propertiesfactorybean""location" "classpath:com/foo/jdbc-production.properties"Propertiesfactorybean@H_502_34@,to instantiate ajava.util.Properties@H_502_34@instance with values loaded from the suppliedResource
location).
After…
<util:properties
location=/>
Before…
<!-- creates a java.util.List instance with values loaded from the supplied sourceList -->
"emails" "org.springframework.beans.factory.config.Listfactorybean""sourceList"<list>
<value>pechorin@hero.org</value>
<value>raskolnikov@slums.org<value>stavrogin@gov.org<value>porfiry@gov.org</value>
</list>
Listfactorybean@H_502_34@,to create ajava.util.List@H_502_34@instance initialized with values taken from the suppliedsourceList@H_502_34@.
After…
<!-- creates a java.util.List instance with the supplied values -->
<util:list "emails"</value>
</value>
</util:list>
You can also explicitly control the exact type ofList@H_502_34@that will be instantiated and populated via the use of thelist-class@H_502_34@attribute on the<util:list/>@H_502_34@element. For example,if we really need ajava.util.LinkedList@H_502_34@to be instantiated,we could use the following configuration:
list-class="java.util.LinkedList"<value>jackshaftoe@vagabond.org<value>eliza@thinkingmanscrumpet.org<value>vanhoek@pirate.org<value>d'Arcachon@nemesis.org</util:list>
If nolist-class@H_502_34@attribute is supplied,aList@H_502_34@implementation will be chosen by the container.
Before…
<!-- creates a java.util.Map instance with values loaded from the supplied sourceMap -->
"org.springframework.beans.factory.config.Mapfactorybean""sourceMap"<map>
<entry key="pechorin" "pechorin@hero.org"/>
"raskolnikov" "raskolnikov@slums.org""stavrogin" "stavrogin@gov.org""porfiry" "porfiry@gov.org"</map>
Mapfactorybean@H_502_34@,242)">java.util.Map@H_502_34@instance initialized with key-value pairs taken from the supplied'sourceMap'@H_502_34@.
After…
<!-- creates a java.util.Map instance with the supplied key-value pairs -->
<util:map </util:map>
You can also explicitly control the exact type ofMap@H_502_34@that will be instantiated and populated via the use of the'map-class'@H_502_34@attribute on the<util:map/>@H_502_34@element. For example,242)">java.util.TreeMap@H_502_34@to be instantiated,127)">map-class="java.util.TreeMap"</util:map>
If no'map-class'@H_502_34@attribute is supplied,242)">Map@H_502_34@implementation will be chosen by the container.
Before…
<!-- creates a java.util.Set instance with values loaded from the supplied sourceSet -->
"org.springframework.beans.factory.config.Setfactorybean""sourceSet"<set>
</set>
Setfactorybean@H_502_34@,242)">java.util.Set@H_502_34@instance initialized with values taken from the supplied'sourceSet'@H_502_34@.
After…
<!-- creates a java.util.Set instance with the supplied values -->
<util:set </util:set>
You can also explicitly control the exact type ofSet@H_502_34@that will be instantiated and populated via the use of the'set-class'@H_502_34@attribute on the<util:set/>@H_502_34@element. For example,242)">java.util.TreeSet@H_502_34@to be instantiated,127)">set-class="java.util.TreeSet"</util:set>
If no'set-class'@H_502_34@attribute is supplied,242)">Set@H_502_34@implementation will be chosen by the container.
Thejee@H_502_34@tags deal with Java EE (Java Enterprise Edition)-related configuration issues,such as looking up a JNDI object and defining EJB references.
To use the tags in thejee@H_502_34@schema,you need to have the following preamble at the top of your Spring XML configuration file; the text in the following snippet references the correct schema so that the tags in thejee@H_502_34@namespace are available to you.
"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">