There are times when you may come across a need to declare a bean in spring context that points to a static field. For example, a bean expecting a static field in one of its constructor parameter.
There are two ways to declare a bean from a static field.
- You either use the spring provided factory bean
FieldRetrievingFactoryBean
or - Use the custom tag
<util:contant>
We will see examples of both cases.
This example uses the following frameworks:
Dependencies
Add the following dependencies:
spring-core
spring-context
spring-beans
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.javarticles.spring</groupId> <artifactId>springListExample</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> </dependencies> <properties> <spring.version>3.2.3.RELEASE</spring.version> </properties> </project>
Basic rules in defining the static fields
Let’s declare the bean for static field java.lang.Integer.MAX_VALUE
. In the below context file, we define the maximum integer value using util:constant
and FieldRetrievingFactoryBean
.
applicationContext.xml:
<?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:context="http://www.springframework.org/schema/context" 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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"> <util:constant static-field="java.lang.Integer.MAX_VALUE" /> <bean id="intMaxValue" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"> <property name="targetClass" value="java.lang.Integer" /> <property name="targetField" value="MAX_VALUE" /> </bean> </beans>
SpringStaticFieldExample:
package com.javarticles.spring; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringStaticFieldExample { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( "applicationContext.xml"); try { Integer max = (Integer) context.getBean("java.lang.Integer.MAX_VALUE"); System.out.println("Maximum value of integer: " + max); } finally { context.close(); } } }
Output:
Maximum value of integer: 2147483647
You have come across the property names targetClass
, targetObject
, targetField
and staticField
. Let me describe the properties for you.
In the above example, the targetClass
is java.lang.Integer
, targetObject
would be a bean for class java.lang.Thread
, the targetField
would be the static field MAX_VALUE
and the staticField
would be the name of the static field, java.lang.Integer.MAX_VALUE
.
There are a number of combinations in which you can define the static fields in spring if you are using the factory bean FieldRetrievingFactoryBean
.
- Using target class and target field combination
- Using target object and target field combination
- Using just the static field
Few minor rules:
- You shouldn’t be providing both target object and target class, spring won’t be able to figure which one to use so it will throw an
IllegalArgumentException
. - If both target object and target class are null, you should not provide target field, else spring will throw
IllegalArgumentException
- If you are not providing target object and target class then you should simply provide the static field name
As long as it knows the target class and target field, it can derive the reference to the static field.
More examples
Let me show you more examples of defining static fields. Below example is about a training session which contains a list of topics to train on. The list of topics are injected using spring.
The topics are defined as static fields in class Topics
.
Topics:
package com.javarticles.spring; public class Topics { public static final String JAVA = "Java"; public static final String SCALA = "Scala"; public static final Language C = new Language("C"); public enum JavaTopicsEnum { CORE, JDBC, CONCURRENCY } }
A simple language bean.
Language:
package com.javarticles.spring; public class Language { private String lang; public Language(String lang) { this.lang = lang; } public String getLang() { return lang; } public String toString() { return "LanguageBean(" + lang + ")"; } }
Training:
package com.javarticles.spring; import java.util.ArrayList; import java.util.List; public class Training { private List<String> languages = new ArrayList<String>(); private Language basicLanguage; public Training(){} public Training(Language basicLanguage){ this.basicLanguage = basicLanguage; } public Language getBasicLanguage() { return basicLanguage; } public void setBasicLanguage(Language basicLanguage) { this.basicLanguage = basicLanguage; } public List<String> getLanguages() { return languages; } public void setLanguages(List<String> languages) { this.languages = languages; } }
Let’s define the static fields in the spring context.
- scalaLanguage – It is defined using the built-in factory bean
FieldRetrievingFactoryBean
and we have specified the fully qualified field name in thestaticField
property - JavaCore – It is defined using the special tag
util:constant
andstatic-field
attribute which contains the fully qualified field name of theenum
field declared withinTopics
class - javaLanguage – It is defined using the built-in factory bean
FieldRetrievingFactoryBean
and properties,tagetObject
andtargetField
- training – Here we define
Training
bean which in turn has a list propertylanguages
built using the static fields. If you note instead of specifying the field name in thestaticField
property explicitly, we have set it as the bean name ofFieldRetrievingFactoryBean
- basicTraining – Its constructor argument points to a static field
applicationContext.xml:
<?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:context="http://www.springframework.org/schema/context" 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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"> <util:constant static-field="java.lang.Integer.MAX_VALUE" /> <bean id="intMaxValue" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"> <property name="targetClass" value="java.lang.Integer" /> <property name="targetField" value="MAX_VALUE" /> </bean> <bean id="scalaLanguage" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"> <property name="staticField" value="com.javarticles.spring.Topics.SCALA" /> </bean> <util:constant id="JavaCore" static-field="com.javarticles.spring.Topics$JavaTopicsEnum.CORE" /> <bean id="topic" class="com.javarticles.spring.Topics" /> <bean id="javaLanguage" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"> <property name="targetObject" ref="topic" /> <property name="targetField" value="JAVA" /> </bean> <bean id="training" class="com.javarticles.spring.Training"> <property name="languages"> <list> <bean name="com.javarticles.spring.Topics.JAVA" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" /> <bean name="com.javarticles.spring.Topics.SCALA" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" /> </list> </property> <property name="basicLanguage"> <util:constant static-field="com.javarticles.spring.Topics.C" /> </property> </bean> <bean id="basicTraining" class="com.javarticles.spring.Training"> <constructor-arg index="0"> <util:constant static-field="com.javarticles.spring.Topics.JAVA" /> </constructor-arg> </bean> </beans>
SpringStaticFieldExample:
package com.javarticles.spring; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringStaticFieldExample { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( "applicationContext.xml"); try { Integer max = (Integer) context.getBean("java.lang.Integer.MAX_VALUE"); System.out.println("Maximum value of integer: " + max); Topics.JavaTopicsEnum javaCore = (Topics.JavaTopicsEnum) context.getBean("JavaCore"); System.out.println("JavaTopicsEnum: " + javaCore); String java = (String) context.getBean("javaLanguage"); System.out.println("JavaLanguage field's value: " + java); System.out.println("SavaLanguage field's value: " + context.getBean("scalaLanguage")); Training training = (Training) context.getBean("training"); System.out.println("Training on languages: " + training.getLanguages()); System.out.println("Basic language: " + training.getBasicLanguage()); Training basicTraining = (Training) context.getBean("basicTraining"); System.out.println("Basic training: " + basicTraining.getBasicLanguage()); } finally { context.close(); } } }
Output:
Maximum value of integer: 2147483647 JavaTopicsEnum: CORE JavaLanguage field's value: Java SavaLanguage field's value: Scala Training on languages: [Java, Scala] Basic language: LanguageBean(C) Basic training: LanguageBean(Java)
Download the source code
In this article I showed you how to declare static fields in spring context. You can download the source code here: springStaticFieldExample.zip