Spring framework源码 Constants学习


声明:本文转载自https://my.oschina.net/kipeng/blog/1789361,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

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

本文发表于2018年04月03日 22:38
(c)注:本文转载自https://my.oschina.net/kipeng/blog/1789361,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 1644 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1