现在的位置: 首页 > 综合 > 正文

Spring配置Bean中注入Enum实例

2013年07月03日 ⁄ 综合 ⁄ 共 3354字 ⁄ 字号 评论关闭

尝试在spring的配置中的bean中注入Enum,debug跟踪了下spring-context 3.2.5.RELEASE的源码。

最终在类org.springframework.beans.TypeConverterDelegate中的attemptToConvertStringToEnum方法中进行了bean中Enum类型属性的转换。

private Object attemptToConvertStringToEnum(Class<?> requiredType, String trimmedValue, Object currentConvertedValue) {
	Object convertedValue = currentConvertedValue;

	if (Enum.class.equals(requiredType)) {
		// target type is declared as raw enum, treat the trimmed value as <enum.fqn>.FIELD_NAME
		int index = trimmedValue.lastIndexOf(".");
		if (index > - 1) {
			String enumType = trimmedValue.substring(0, index);
			String fieldName = trimmedValue.substring(index + 1);
			ClassLoader loader = this.targetObject.getClass().getClassLoader();
			try {
				Class<?> enumValueType = loader.loadClass(enumType);
				Field enumField = enumValueType.getField(fieldName);
				convertedValue = enumField.get(null);
			}
			catch (ClassNotFoundException ex) {
				if(logger.isTraceEnabled()) {
					logger.trace("Enum class [" + enumType + "] cannot be loaded from [" + loader + "]", ex);
				}
			}
			catch (Throwable ex) {
				if(logger.isTraceEnabled()) {
					logger.trace("Field [" + fieldName + "] isn't an enum value for type [" + enumType + "]", ex);
				}
			}
		}
	}

	if (convertedValue == currentConvertedValue) {
		// Try field lookup as fallback: for JDK 1.5 enum or custom enum
		// with values defined as static fields. Resulting value still needs
		// to be checked, hence we don't return it right away.
		try {
			Field enumField = requiredType.getField(trimmedValue);
			convertedValue = enumField.get(null);
		}
		catch (Throwable ex) {
			if (logger.isTraceEnabled()) {
				logger.trace("Field [" + convertedValue + "] isn't an enum value", ex);
			}
		}
	}

	return convertedValue;
}

在上面第一个if分支可以看出可在bean中注入Enum实例。在第二个if分支中可以看出能直接注入enum类型的属性。另外从这段代码的处理逻辑,可以看出不仅能注入enum实例,同时可以注入属性类型的静态属性。下面简单的写了个测试

Father.java

package com.jack.test;


public class Father {
	public static final Father INSTANCE = new Father();
}

PersonType.java

package com.jack.test;


public enum PersonType {
	STUDENT, TEACHER;
}

Sex.java

package com.jack.test;


public enum Sex {
	MALE, FEMALE;
}

Person.java

package com.jack.test;


public class Person {
	private Father father;
	private PersonType type;
	private Enum<Sex> sex;


	public Enum<Sex> getSex() {
		return sex;
	}


	public void setSex(Enum<Sex> sex) {
		this.sex = sex;
	}


	public Father getFather() {
		return father;
	}


	public void setFather(Father father) {
		this.father = father;
	}


	public PersonType getType() {
		return type;
	}


	public void setType(PersonType type) {
		this.type = type;
	}
}

App.java

package com.jack.test;


import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.util.Assert;


/**
 * @author jack.L
 */
public class App {
	public static void main(String[] args) {


		try (ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("context.xml")) {
			Person person = ctx.getBean(Person.class);
			Assert.isTrue(person.getFather() == Father.INSTANCE);
			Assert.isTrue(person.getType() == PersonType.STUDENT);
			Assert.isTrue(person.getSex() == Sex.MALE);
		}
	}
}

context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	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-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<bean id="person" class="com.jack.test.Person" p:father="INSTANCE"
		p:type="STUDENT" p:sex="com.jack.test.Sex.MALE" />

</beans>

抱歉!评论已关闭.