Spring framework源码 Constants学习

最近在学习Spring源码的时候发现有个工具写的蛮不错的,所以分享出来

在AbstractPlatformTransactionManager类中,使用一个String类型的name获取对应常量的值

public final void setTransactionSynchronizationName(String constantName) {
		setTransactionSynchronization(constants.asNumber(constantName).intValue());
	}

源码学习

Constants是一个常量获取工具,在org.springframework.core包中

This class can be used to parse other classes containing constant definitions

in public static final members. The {@code asXXXX} methods of this class

allow these constant values to be accessed via their string names.

构造函数:通过反射的方式获取目标source类中所有的public static final的常量放入一个Map中

public Constants(Class<?> clazz) {
		Assert.notNull(clazz, "Class must not be null");
		this.className = clazz.getName();
		Field[] fields = clazz.getFields();
		for (Field field : fields) {
			if (ReflectionUtils.isPublicStaticFinal(field)) {
				String name = field.getName();
				try {
					Object value = field.get(null);
					this.fieldCache.put(name, value);
				}
				catch (IllegalAccessException ex) {
					// just leave this field and continue
				}
			}
		}
	}

将获取的常量存放在一个Map中

/** The name of the introspected class */
	private final String className;

	/** Map from String field name to object value */
	private final Map<String, Object> fieldCache = new HashMap<>();

常用的几个方法:通过asXX方法取出相应的值

/**
	 * Return a constant value cast to a Number.
	 * @param code the name of the field (never {@code null})
	 * @return the Number value
	 * @see #asObject
	 * @throws ConstantException if the field name wasn't found
	 * or if the type wasn't compatible with Number
	 */
	public Number asNumber(String code) throws ConstantException {
		Object obj = asObject(code);
		if (!(obj instanceof Number)) {
			throw new ConstantException(this.className, code, "not a Number");
		}
		return (Number) obj;
	}

	/**
	 * Return a constant value as a String.
	 * @param code the name of the field (never {@code null})
	 * @return the String value
	 * Works even if it's not a string (invokes {@code toString()}).
	 * @see #asObject
	 * @throws ConstantException if the field name wasn't found
	 */
	public String asString(String code) throws ConstantException {
		return asObject(code).toString();
	}

	/**
	 * Parse the given String (upper or lower case accepted) and return
	 * the appropriate value if it's the name of a constant field in the
	 * class that we're analysing.
	 * @param code the name of the field (never {@code null})
	 * @return the Object value
	 * @throws ConstantException if there's no such field
	 */
	public Object asObject(String code) throws ConstantException {
		Assert.notNull(code, "Code must not be null");
		String codeToUse = code.toUpperCase(Locale.ENGLISH);
		Object val = this.fieldCache.get(codeToUse);
		if (val == null) {
			throw new ConstantException(this.className, codeToUse, "not found");
		}
		return val;
	}

使用demo:

import org.springframework.core.Constants;

/**
 * @Author: Kipeng Huang
 * @Date: 2018-4-3 15:52
 */
public class ConstantsLearn {
    public static final int MAX_NUM = 5;
    public static final int MIN_NUM = 2;
    public static final String NAME = "kipeng";
    public static void main(String[] args) {
        Constants constants = new Constants(ConstantsLearn.class);
        System.out.println("MAX_NUM:"+constants.asNumber("MAX_NUM").intValue());
        System.out.println("NAME:"+constants.asString("NAME"));
    }

}

运行结果:

MAX_NUM:5
NAME:kipeng

注意事项:

常量必须是 public static final 修饰的,否则使用asXX方法取出的时候抛exception

public ConstantException(String className, String field, String message) {
			super("Field '" + field + "' " + message + " in class [" + className + "]");
		}

反射的知识补充

在Constants的构造函数中使用了java反射的部分内容,所以补充下反射的部分知识

  • getName 获取类名 包含了包名
  • getSimpleName 获取简单的类名 不包含包名
  • getFields 获取全部public 的参数
  • getDeclaredFields 获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段
  • getMethods 获取全部public 的methods
  • getDeclaredMethods 获取全部的method including public, protected, default (package) access, and private methods, but excluding inherited methods

猜你喜欢

转载自my.oschina.net/kipeng/blog/1789361
今日推荐