说完 Invoker
接口,我们继续看 Reflector
对象依赖的 PropertyNamer
对象。
PropertyNamer
对象是mybatis中提供的一个处理属性的工具类,它主要用于获取 getter
/ setter
方法对应的属性名称,校验方法名称是否是 getter
/ setter
方法,以及判断方法可以获取属性名称。
PropertyNamer
提供了四个静态方法完成了上述的功能:
methodToProperty
方法用于将方法名称转属性名称,在处理方式上, PropertyNamer
会移除掉方法名称的 get
/ set
/ is
前缀,获取到对应的属性名称,之后根据 Java Bean
规范,
大部分场景下,需要将获取到的属性名称的首字母转为小写,但是为了支持偶尔出现的全大写的名称,所以会检查前两个字符是否都是大写,如果是的话,就不进行处理。 /** * 方法名称转属性名称 * * @param name 方法名称 * @return 属性名 */ public static String methodToProperty(String name) { // 只处理 is/get/set开头的方法名称 if (name.startsWith("is")) { name = name.substring(2); } else if (name.startsWith("get") || name.startsWith("set")) { name = name.substring(3); } else { throw new ReflectionException("Error parsing property name '" + name + "'. Didn't start with 'is', 'get' or 'set'."); } // 在Java Bean规范中,通常会将获取到的属性名称的第一个字母转为小写, // 但是为了支持偶尔出现的全大写的名称,检查前两个字符是否都是大写,如果是的话,就不进行处理。 // 属性名首字母小写 Name=>name.MyName=>myName,MYName=>MYName // 属性名的长度为1,或者属性名长度大于1的同时属性名的第二个字符不是大写的。 if (name.length() == 1/*属性名长度为1*/ || (name.length() > 1 && !Character.isUpperCase(name.charAt(1)))/**/ ) { // 首字母小写 name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1); } return name; } 复制代码
isProperty
方法用于判断指定方法可以获取属性名称,实现比较简单,实际上就是判断方法是否是一个有效的 getter
/ setter
方法。 /** * 判断指定方法可以获取属性名称 * @param name 方法名 * @return 指定方法是否对应着属性名称 */ public static boolean isProperty(String name) { return name.startsWith("get") || name.startsWith("set") || name.startsWith("is"); } 复制代码
isGetter
方法用于判断指定方法是否为 getter
方法,实现就是简单判断方法名称是否以 get
/ is
开头。 /** * 判断指定方法是否为getter方法 * @param name 方法名称 * @return 指定方法是否为getter方法 */ public static boolean isGetter(String name) { return name.startsWith("get") || name.startsWith("is"); } 复制代码
isSetter
方法用于判断指定方法是否为 setter
方法,实现就是简单判断方法名称是否以 set
开头。 /** * 判断指定方法是否为setter方法 * @param name 方法名称 * @return 指定方法是否为setter方法 */ public static boolean isSetter(String name) { return name.startsWith("set"); } 复制代码
之后我们看一下,实现比较复杂的 TypeParameterResolver
类。