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 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:5NAME: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


分享到:


相關文章: