Mybatis反射核心類Reflector的實(shí)現(xiàn)
Reflector類負(fù)責(zé)對(duì)一個(gè)類進(jìn)行反射解析,并將解析后的結(jié)果在屬性中存儲(chǔ)起來(lái)。
一個(gè)類反射解析后都有哪些屬性呢?我們可以通過(guò)Reflector類定義的屬性來(lái)查看
public class Reflector {
// 要被反射解析的類
private final Class<?> type;
// 可讀屬性列表即有g(shù)et方法的屬性列表
private final String[] readablePropertyNames;
// 可寫(xiě)屬性列表即有set方法的屬性列表
private final String[] writeablePropertyNames;
// set方法映射表。鍵為屬性名,值為對(duì)應(yīng)的set方法
private final Map<String, Invoker> setMethods = new HashMap<String, Invoker>();
// get方法映射表。鍵為屬性名,值為對(duì)應(yīng)的get方法
private final Map<String, Invoker> getMethods = new HashMap<String, Invoker>();
// set方法輸入?yún)?shù)類型映射表。鍵為屬性名,值為對(duì)應(yīng)set方法輸入?yún)?shù)類型的Class
private final Map<String, Class<?>> setTypes = new HashMap<String, Class<?>>();
// get方法返回值類型映射表。鍵為屬性名,值為對(duì)應(yīng)get方法返回值類型的Class
private final Map<String, Class<?>> getTypes = new HashMap<String, Class<?>>();
// 默認(rèn)構(gòu)造器
private Constructor<?> defaultConstructor;
// 忽略大小寫(xiě)的屬性映射表。鍵為屬性名全大寫(xiě)值,值為屬性名
private Map<String, String> caseInsensitivePropertyMap = new HashMap<String, String>();
// Reflector類反射解析一個(gè)類的過(guò)程是由構(gòu)造函數(shù)觸發(fā)的
public Reflector(Class<?> clazz) {
// 記錄被反射解析的類
type = clazz;
// 解析默認(rèn)造方法
addDefaultConstructor(clazz);
// 解析所有的getter
addGetMethods(clazz);
// 解析所有的setter
addSetMethods(clazz);
// 解析所有屬性
addFields(clazz);
// 獲取可讀屬性列表
readablePropertyNames = getMethods.keySet().toArray(new String[getMethods.keySet().size()]);
// 獲取可寫(xiě)屬性列表
writeablePropertyNames = setMethods.keySet().toArray(new String[setMethods.keySet().size()]);
// 獲取忽略大小寫(xiě)的屬性列表
for (String propName : readablePropertyNames) {
caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName);
}
for (String propName : writeablePropertyNames) {
caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName);
}
}
.....
}
創(chuàng)建方式:
1、直接new Reflector reflector = new Reflector(User.class); 2、工廠創(chuàng)建 ReflectorFactory reflectorFactory = new DefaultReflectorFactory(); Reflector reflector = reflectorFactory.findForClass(User.class);
對(duì)外暴露的方法:
Reflector reflector = new Reflector(User.class);
// 獲取被解析反射的類
Class<?> type = reflector.getType();
// 根據(jù)屬性名獲取對(duì)應(yīng)的set方法
Invoker setInvoker = reflector.getSetInvoker("name");
// 根據(jù)屬性名獲取對(duì)應(yīng)的get方法
Invoker getInvoker = reflector.getGetInvoker("name");
// 獲取所有可讀屬性列表
String[] getablePropertyNames = reflector.getGetablePropertyNames();
// 獲取所有可寫(xiě)屬性列表
String[] setablePropertyNames = reflector.getSetablePropertyNames();
// 獲取默認(rèn)構(gòu)造器
Constructor<?> defaultConstructor = reflector.getDefaultConstructor();
// 根據(jù)屬性名獲取對(duì)應(yīng)get方法返回值類型
Class<?> getterType = reflector.getGetterType("name");
// 根據(jù)屬性名獲取對(duì)應(yīng)set方法參數(shù)類型
Class<?> setterType = reflector.getSetterType("name");
// 根據(jù)屬性名不區(qū)分大小寫(xiě)獲取屬性名
String name = reflector.findPropertyName("name");
// 判斷屬性是否存在getter方法
boolean hasGetter = reflector.hasGetter("name");
// 判斷屬性是否存在getter方法
boolean hasSetter = reflector.hasSetter("name");
測(cè)試案例:
@Test
public void test1()throws Exception{
Reflector reflector = new Reflector(User.class);
Class<?> type = reflector.getType();
System.out.println("要被反射解析的類:"+type);
Constructor<?> defaultConstructor = reflector.getDefaultConstructor();
System.out.println(defaultConstructor);
String[] getablePropertyNames = reflector.getGetablePropertyNames();
for (String propertyName : getablePropertyNames) {
System.out.println("可讀屬性:"+propertyName);
}
System.out.println("----------------------------------------------------------");
String[] setablePropertyNames = reflector.getSetablePropertyNames();
for (String propertyName : setablePropertyNames) {
System.out.println("可寫(xiě)屬性:"+propertyName);
}
System.out.println("--------------------------------------------------");
for (String propertyName : reflector.getGetablePropertyNames()) {
Invoker name = reflector.getGetInvoker(propertyName);
Object invoke = name.invoke(new User(), null);
System.out.println("執(zhí)行屬性"+propertyName+"的get方法:"+invoke);
}
}
測(cè)試結(jié)果:

該類里面還有一個(gè)值的注意的小工具類可以直接拿來(lái)使用,生成方法簽名
private String getSignature(Method method) {
StringBuilder sb = new StringBuilder();
Class<?> returnType = method.getReturnType();
if (returnType != null) {
sb.append(returnType.getName()).append('#');
}
sb.append(method.getName());
Class<?>[] parameters = method.getParameterTypes();
for (int i = 0; i < parameters.length; i++) {
if (i == 0) {
sb.append(':');
} else {
sb.append(',');
}
sb.append(parameters[i].getName());
}
return sb.toString();
}到此這篇關(guān)于Mybatis反射核心類Reflector的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Mybatis反射核心類Reflector內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java中判斷對(duì)象是否相等的equals()方法使用教程
與==運(yùn)算符響應(yīng),equals()方法也是Java中對(duì)對(duì)象進(jìn)行比較的一大方式,要特別注意二者的不同點(diǎn),這個(gè)我們?cè)谙挛闹屑磳⒅v到,接下來(lái)我們就來(lái)看一下Java中判斷對(duì)象是否相等的equals()方法使用教程2016-05-05
CommonMark 使用教程:將 Markdown 語(yǔ)法轉(zhuǎn)成 Html
這篇文章主要介紹了CommonMark 使用教程:將 Markdown 語(yǔ)法轉(zhuǎn)成 Html,這個(gè)技巧我們做任何網(wǎng)站都可以用到,而且非常好用。,需要的朋友可以參考下2019-06-06
詳解Java七大阻塞隊(duì)列之SynchronousQueue
SynchronousQueue不需要存儲(chǔ)線程間交換的數(shù)據(jù),它的作用像是一個(gè)匹配器,使生產(chǎn)者和消費(fèi)者一一匹配。本文詳細(xì)講解了Java七大阻塞隊(duì)列之一SynchronousQueue,需要了解的小伙伴可以參考一下這篇文章2021-09-09
mybatis-plus動(dòng)態(tài)數(shù)據(jù)源讀寫(xiě)分離方式
在分布式項(xiàng)目開(kāi)發(fā)中,動(dòng)態(tài)數(shù)據(jù)源的配置與使用至關(guān)重要,通過(guò)創(chuàng)建DynamicDatasourceService,實(shí)現(xiàn)數(shù)據(jù)源的動(dòng)態(tài)添加與調(diào)用,有效管理主從庫(kù)操作,減輕數(shù)據(jù)庫(kù)壓力,此外,通過(guò)配置類與@DS注解,實(shí)現(xiàn)了靈活的分庫(kù)查詢功能,為高效處理數(shù)據(jù)提供了強(qiáng)有力的支持2024-10-10
教你怎么用Java完成人民幣大寫(xiě)轉(zhuǎn)化
這篇文章主要介紹了教你怎么用Java完成人民幣大寫(xiě)轉(zhuǎn)化,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很好的幫助,需要的朋友可以參考下2021-04-04
基于java實(shí)現(xiàn)停車場(chǎng)管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了基于java實(shí)現(xiàn)停車場(chǎng)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
javamail實(shí)現(xiàn)注冊(cè)激活郵件
這篇文章主要為大家詳細(xì)介紹了javamail實(shí)現(xiàn)注冊(cè)激活郵件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
Java之使用POI教你玩轉(zhuǎn)Excel導(dǎo)入與導(dǎo)出
這篇文章主要介紹了Java之使用POI教你玩轉(zhuǎn)Excel導(dǎo)入與導(dǎo)出,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10

