文档章节

Spring framework源码 Constants学习

kipeng300
 kipeng300
发布于 2018/04/03 16:25
字数 723
阅读 3K
收藏 10

最近在学习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

© 著作权归作者所有

kipeng300
粉丝 7
博文 40
码字总数 26752
作品 0
浦东
程序员
私信 提问
加载中

评论(2)

kipeng300
kipeng300 博主

引用来自“首席的哥队长”的评论

恕我不明白,为什么要这样绕一绕,常量直接用不好么?
其实很多时候比如xml配置的时候我们直接写一个字串会比较方便,这样只需要写常量名称就可以。当然也可以直接写具体的值。

像AbstractPlatformTransactionManager中的setTransactionSynchronizationName就是直接传入一个name即可或者直接出入一个具体的value

```java
/**
   * Set the transaction synchronization by the name of the corresponding constant
   * in this class, e.g. "SYNCHRONIZATION_ALWAYS".
   * @param constantName name of the constant
   * @see #SYNCHRONIZATION_ALWAYS
   */
  public final void setTransactionSynchronizationName(String constantName) {
    setTransactionSynchronization(constants.asNumber(constantName).intValue());
  }
public final void setTransactionSynchronization(int transactionSynchronization) {
    this.transactionSynchronization = transactionSynchronization;
  }
```

首席的哥队长
首席的哥队长
恕我不明白,为什么要这样绕一绕,常量直接用不好么?
Spring Kafka 1.3.6 和 2.1.8 发布,Spring 的 Kafka 抽象

Spring Kafka 1.3.6 和 2.1.8 已发布,更新内容如下: 2.1.8 更新日志: Upgrade to Spring Data Kay SR9 Upgrade Spring Framework, Data, Clients versions GH-753: Close transactional ......

淡漠悠然
2018/07/29
985
0
SVN 签出源码 Struts Spring Hibernate

很多优秀的开源项目已经提供SVN源码签出了,无论是解疑还是学习,都是一大幸福之事啊! Apache的SVN库,强烈推荐! http://svn.apache.org/repos/asf/ 里面不但有Struts的源码,还有著名的A...

scofi06
2010/09/02
711
0
Spring Framework 5.1 RC3, 5.0.9 和 4.3.19 发布

Spring Framework 的三个分支发布了更新,分别是 Spring Framework 5.1 RC3, 5.0.9 和 4.3.19。而它们的更新内容主要是 bug 修复以及一些其他的改进。 具体内容请点击链接查看 5.0.9 4.3.19...

淡漠悠然
2018/09/10
1.8K
2
Intellij idea----编译导入spring framework源码

编译spring framework源码,网上已经很多了,自己亲手操作一下,记录一把。 总体来讲,按照spring framework在github上写的操作步骤一步一步来就没事的,网上很多人针对不同版本自己增加了一...

checkboxMan
2018/11/28
975
0
本科文凭样本自考大专文凭样本 高中文凭样本 中专文凭样本

你可能正在想“Spring不过是另外一个的framework”(英语释义:框架,骨架;结构,构架)。当已经有许多开放源代码(和专有)J2EEframework时,我们为什么还需要Spring Framework? Spring是独特...

spring小小鸟
2018/08/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Batch 配置一个步骤(Step)

如我们在 域语言(Domain Language)章节中讨论的内容一致,一个 步骤(Step)是一个独立封装了执行顺序的批量作业(Job),并且包含有用于定义和控制一个批量作业的所有独立信息。 针对这个...

honeymoose
今天
34
0
郑州哪里可以开五金工具发票-郑州新闻网

郑州哪里可以开五金工具发票【1.3.2 - 2.9.3.0 - 0.5.6.8.】李生,adb的全称为Android Debug Bridge,是Android手机通用的一个USB端口。百度CarLife的部分车机采用...

提供格
今天
38
0
郑州哪里可以开五金材料发票-郑州新闻网

郑州哪里可以开五金材料发票【1.3.2 - 2.9.3.0 - 0.5.6.8.】李生,adb的全称为Android Debug Bridge,是Android手机通用的一个USB端口。百度CarLife的部分车机采用...

法放饭
今天
43
0
郑州哪里可以开劳保用品发票-郑州新闻网

郑州哪里可以开劳保用品发票【1.3.2 - 2.9.3.0 - 0.5.6.8.】李生,adb的全称为Android Debug Bridge,是Android手机通用的一个USB端口。百度CarLife的部分车机采用...

多徐重
今天
31
0
centos php ppt转图片

参考:https://blog.csdn.net/aituochang1886/article/details/101167564 安装 Unoconv 参考: https://www.licongying.cn/2018/10/linux-centos-install-unoconv-liboffice/ https://blog.c......

四季变幻
今天
29
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部