一.基础支持层
MyBatis的架构可以分为三层,分别是接口层,核心处理层以及基础支持层,按照从下至上的方式先从基础支持层开始,基础支持层具体有:
1.解析器模块 2.反射模块 3.异常模块 4.数据源模块 5.事务模块 6.缓存模块 7.类型模块 8.IO模块 9.日志模块 10.注解模块 11.Binding模块
1.解析器模块
对应的是parsing包,主要有两个功能:1.是对于XPath的封装,为MyBatis初始化时解析mybatis-config.xml提供支持。
2.处理动态SQL语句中的占位符提供支持
XPathParser类用来解析XML配置文件:
public class XPathParser {
//XML解析后的Document对象
private final Document document;
//是否需要验证
private boolean validation;
//XML实体解析器,就是用来获得本地的DTD或者XSD文件
private EntityResolver entityResolver;
//Properties对象。用来替换需要动态配置的属性值,例如${username}
private Properties variables;
//XPath对象,用来查找XML中的节点和元素
private XPath xpath;
public XPathParser(String xml) {
commonConstructor(false, null, null);
this.document = createDocument(new InputSource(new StringReader(xml)));
}
public XPathParser(Reader reader) {
commonConstructor(false, null, null);
this.document = createDocument(new InputSource(reader));
}
public XPathParser(InputStream inputStream) {
commonConstructor(false, null, null);
this.document = createDocument(new InputSource(inputStream));
}
public XPathParser(Document document) {
commonConstructor(false, null, null);
this.document = document;
}
public XPathParser(String xml, boolean validation) {
commonConstructor(validation, null, null);
this.document = createDocument(new InputSource(new StringReader(xml)));
}
public XPathParser(Reader reader, boolean validation) {
commonConstructor(validation, null, null);
this.document = createDocument(new InputSource(reader));
}
public XPathParser(InputStream inputStream, boolean validation) {
commonConstructor(validation, null, null);
this.document = createDocument(new InputSource(inputStream));
}
public XPathParser(Document document, boolean validation) {
commonConstructor(validation, null, null);
this.document = document;
}
public XPathParser(String xml, boolean validation, Properties variables) {
commonConstructor(validation, variables, null);
this.document = createDocument(new InputSource(new StringReader(xml)));
}
public XPathParser(Reader reader, boolean validation, Properties variables) {
commonConstructor(validation, variables, null);
this.document = createDocument(new InputSource(reader));
}
public XPathParser(InputStream inputStream, boolean validation, Properties variables) {
commonConstructor(validation, variables, null);
this.document = createDocument(new InputSource(inputStream));
}
public XPathParser(Document document, boolean validation, Properties variables) {
commonConstructor(validation, variables, null);
this.document = document;
}
//最有代表性的构造方法,输入xml地址以及是否需要验证,properties和EntityResolver
public XPathParser(String xml, boolean validation, Properties variables, EntityResolver entityResolver) {
commonConstructor(validation, variables, entityResolver);
this.document = createDocument(new InputSource(new StringReader(xml)));
}
public XPathParser(Reader reader, boolean validation, Properties variables, EntityResolver entityResolver) {
commonConstructor(validation, variables, entityResolver);
this.document = createDocument(new InputSource(reader));
}
public XPathParser(InputStream inputStream, boolean validation, Properties variables, EntityResolver entityResolver) {
commonConstructor(validation, variables, entityResolver);
this.document = createDocument(new InputSource(inputStream));
}
public XPathParser(Document document, boolean validation, Properties variables, EntityResolver entityResolver) {
commonConstructor(validation, variables, entityResolver);
this.document = document;
}
public void setVariables(Properties variables) {
this.variables = variables;
}
//接下来很多*eval的方法,通过设置returnType后用evalute解析
public String evalString(String expression) {
return evalString(document, expression);
}
public String evalString(Object root, String expression) {
String result = (String) evaluate(expression, root, XPathConstants.STRING);
result = PropertyParser.parse(result, variables);
return result;
}
public Boolean evalBoolean(String expression) {
return evalBoolean(document, expression);
}
public Boolean evalBoolean(Object root, String expression) {
return (Boolean) evaluate(expression, root, XPathConstants.BOOLEAN);
}
public Short evalShort(String expression) {
return evalShort(document, expression);
}
public Short evalShort(Object root, String expression) {
return Short.valueOf(evalString(root, expression));
}
public Integer evalInteger(String expression) {
return evalInteger(document, expression);
}
public Integer evalInteger(Object root, String expression) {
return Integer.valueOf(evalString(root, expression));
}
public Long evalLong(String expression) {
return evalLong(document, expression);
}
public Long evalLong(Object root, String expression) {
return Long.valueOf(evalString(root, expression));
}
public Float evalFloat(String expression) {
return evalFloat(document, expression);
}
public Float evalFloat(Object root, String expression) {
return Float.valueOf(evalString(root, expression));
}
public Double evalDouble(String expression) {
return evalDouble(document, expression);
}
public Double evalDouble(Object root, String expression) {
return (Double) evaluate(expression, root, XPathConstants.NUMBER);
}
public List<XNode> evalNodes(String expression) {
return evalNodes(document, expression);
}
//用来获取node类型的节点
public List<XNode> evalNodes(Object root, String expression) {
List<XNode> xnodes = new ArrayList<>();
NodeList nodes = (NodeList) evaluate(expression, root, XPathConstants.NODESET);
for (int i = 0; i < nodes.getLength(); i++) {
xnodes.add(new XNode(this, nodes.item(i), variables));
}
return xnodes;
}
public XNode evalNode(String expression) {
return evalNode(document, expression);
}
public XNode evalNode(Object root, String expression) {
Node node = (Node) evaluate(expression, root, XPathConstants.NODE);
if (node == null) {
return null;
}
return new XNode(this, node, variables);
}
//根据expression表达式 指定节点以及返回类型来返回对应的值
private Object evaluate(String expression, Object root, QName returnType) {
try {
return xpath.evaluate(expression, root, returnType);
} catch (Exception e) {
throw new BuilderException("Error evaluating XPath. Cause: " + e, e);
}
}
//将XML文件解析成Document对象
private Document createDocument(InputSource inputSource) {
// important: this must only be called AFTER common constructor
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(validation);
factory.setNamespaceAware(false);
factory.setIgnoringComments(true);
factory.setIgnoringElementContentWhitespace(false);
factory.setCoalescing(false);
factory.setExpandEntityReferences(true);
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setEntityResolver(entityResolver);
builder.setErrorHandler(new ErrorHandler() {
@Override
public void error(SAXParseException exception) throws SAXException {
throw exception;
}
@Override
public void fatalError(SAXParseException exception) throws SAXException {
throw exception;
}
@Override
public void warning(SAXParseException exception) throws SAXException {
}
});
return builder.parse(inputSource);
} catch (Exception e) {
throw new BuilderException("Error creating document instance. Cause: " + e, e);
}
}
private void commonConstructor(boolean validation, Properties variables, EntityResolver entityResolver) {
this.validation = validation;
this.entityResolver = entityResolver;
this.variables = variables;
XPathFactory factory = XPathFactory.newInstance();
this.xpath = factory.newXPath();
}
}
XMLMapperEntityResolver,实现 EntityResolver 接口,MyBatis 自定义 EntityResolver 实现类,用于加载本地的 mybatis-3-config.dtd 和 mybatis-3-mapper.dtd 这两个 DTD 文件。
public class XMLMapperEntityResolver implements EntityResolver {
private static final String IBATIS_CONFIG_SYSTEM = "ibatis-3-config.dtd";
private static final String IBATIS_MAPPER_SYSTEM = "ibatis-3-mapper.dtd";
private static final String MYBATIS_CONFIG_SYSTEM = "mybatis-3-config.dtd";
private static final String MYBATIS_MAPPER_SYSTEM = "mybatis-3-mapper.dtd";
//本地mybatis-config.dtd
private static final String MYBATIS_CONFIG_DTD = "org/apache/ibatis/builder/xml/mybatis-3-config.dtd";
//本地mybatis-mapper.dtd 文件
private static final String MYBATIS_MAPPER_DTD = "org/apache/ibatis/builder/xml/mybatis-3-mapper.dtd";
@Override
public InputSource resolveEntity(String publicId, String systemId) throws SAXException {
try {
if (systemId != null) {
String lowerCaseSystemId = systemId.toLowerCase(Locale.ENGLISH);
if (lowerCaseSystemId.contains(MYBATIS_CONFIG_SYSTEM) || lowerCaseSystemId.contains(IBATIS_CONFIG_SYSTEM)) {
return getInputSource(MYBATIS_CONFIG_DTD, publicId, systemId);
} else if (lowerCaseSystemId.contains(MYBATIS_MAPPER_SYSTEM) || lowerCaseSystemId.contains(IBATIS_MAPPER_SYSTEM)) {
return getInputSource(MYBATIS_MAPPER_DTD, publicId, systemId);
}
}
return null;
} catch (Exception e) {
throw new SAXException(e.toString());
}
}
private InputSource getInputSource(String path, String publicId, String systemId) {
InputSource source = null;
if (path != null) {
try {
InputStream in = Resources.getResourceAsStream(path);
source = new InputSource(in);
source.setPublicId(publicId);
source.setSystemId(systemId);
} catch (IOException e) {
// ignore, null is ok
}
}
return source;
}
}
GenericTokenParser,通用的Token解析器
public class GenericTokenParser {
//开始的Token字符串
private final String openToken;
//结束的Token字符串
private final String closeToken;
private final TokenHandler handler;
public GenericTokenParser(String openToken, String closeToken, TokenHandler handler) {
this.openToken = openToken;
this.closeToken = closeToken;
this.handler = handler;
}
public String parse(String text) {
if (text == null || text.isEmpty()) {
return "";
}
// search open token
//寻找开始的openToken位置
int start = text.indexOf(openToken, 0);
if (start == -1) {
return text;
}
char[] src = text.toCharArray();
//起始查找位置
int offset = 0;
final StringBuilder builder = new StringBuilder();
StringBuilder expression = null;
while (start > -1) {
if (start > 0 && src[start - 1] == '\\') {
// this open token is escaped. remove the backslash and continue.
// 添加 [offset, start - offset - 1] 和 openToken 的内容,添加到 builder 中
builder.append(src, offset, start - offset - 1).append(openToken);
offset = start + openToken.length();
} else {
// found open token. let's search close token.
//创建/重置expression对象
if (expression == null) {
expression = new StringBuilder();
} else {
expression.setLength(0);
}
// 添加 offset 和 openToken 之间的内容,添加到 builder 中
builder.append(src, offset, start - offset);
offset = start + openToken.length();
int end = text.indexOf(closeToken, offset);
while (end > -1) {
if (end > offset && src[end - 1] == '\\') {
// this close token is escaped. remove the backslash and continue.
// 添加 [offset, end - offset - 1] 和 endToken 的内容,添加到 builder 中
expression.append(src, offset, end - offset - 1).append(closeToken);
offset = end + closeToken.length();
// 寻找结束的 closeToken 的位置
end = text.indexOf(closeToken, offset);
} else {
// 添加 [offset, end - offset] 的内容,添加到 builder 中
expression.append(src, offset, end - offset);
offset = end + closeToken.length();
break;
}
}
if (end == -1) {
// close token was not found.
// closeToken 未找到,直接拼接
builder.append(src, start, src.length - start);
// 修改 offset
offset = src.length;
} else {
builder.append(handler.handleToken(expression.toString()));
offset = end + closeToken.length();
}
}
// 继续,寻找开始的 openToken 的位置
start = text.indexOf(openToken, offset);
}
// 拼接剩余的部分
if (offset < src.length) {
builder.append(src, offset, src.length - offset);
}
return builder.toString();
}
}
其实paser方法就是处理token将其转换成一个规范的token表达,具体操作交给TokenHandler
PropertyParser
public class PropertyParser {
private static final String KEY_PREFIX = "org.apache.ibatis.parsing.PropertyParser.";
public static final String KEY_ENABLE_DEFAULT_VALUE = KEY_PREFIX + "enable-default-value";
public static final String KEY_DEFAULT_VALUE_SEPARATOR = KEY_PREFIX + "default-value-separator";
private static final String ENABLE_DEFAULT_VALUE = "false";
private static final String DEFAULT_VALUE_SEPARATOR = ":";
//是为了禁止构造PropertyParser对象
private PropertyParser() {
// Prevent Instantiation
}
public static String parse(String string, Properties variables) {
//创建VariableTokenHandler对象
VariableTokenHandler handler = new VariableTokenHandler(variables);
//创建 GenericTokenParser 对象
GenericTokenParser parser = new GenericTokenParser("${", "}", handler);
//执行解析
return parser.parse(string);
}
private static class VariableTokenHandler implements TokenHandler {
//Properties对象
private final Properties variables;
//是否开启默认值功能,默认为不开启
private final boolean enableDefaultValue;
//默认值的分隔符
private final String defaultValueSeparator;
private VariableTokenHandler(Properties variables) {
this.variables = variables;
this.enableDefaultValue = Boolean.parseBoolean(getPropertyValue(KEY_ENABLE_DEFAULT_VALUE, ENABLE_DEFAULT_VALUE));
this.defaultValueSeparator = getPropertyValue(KEY_DEFAULT_VALUE_SEPARATOR, DEFAULT_VALUE_SEPARATOR);
}
private String getPropertyValue(String key, String defaultValue) {
return (variables == null) ? defaultValue : variables.getProperty(key, defaultValue);
}
@Override
public String handleToken(String content) {
if (variables != null) {
String key = content;
//开启默认值功能
if (enableDefaultValue) {
//查找默认值
final int separatorIndex = content.indexOf(defaultValueSeparator);
String defaultValue = null;
if (separatorIndex >= 0) {
key = content.substring(0, separatorIndex);
defaultValue = content.substring(separatorIndex + defaultValueSeparator.length());
}
//不存在就返回默认值
if (defaultValue != null) {
return variables.getProperty(key, defaultValue);
}
}
if (variables.containsKey(key)) {
return variables.getProperty(key);
}
}
return "${" + content + "}";
}
}
}
TokenHandler
public interface TokenHandler {
String handleToken(String content);
}
2.反射模块
对于原生的反射进行了良好的封装提供了更加简洁易用的API,方便上层调用。
首先是Reflector类,会缓存反射操作需要的类的信息。每个反射器都对应着一个类。
public class Reflector {
private final Class<?> type;//对应的class
private final String[] readablePropertyNames;//可读属性的名称集合,存在get方法即可读
private final String[] writeablePropertyNames;//可写属性的名称集合,存在set方法即可写
private final Map<String, Invoker> setMethods = new HashMap<>();//保存属性相关的set方法
private final Map<String, Invoker> getMethods = new HashMap<>();//保存属性相关的get方法
private final Map<String, Class<?>> setTypes = new HashMap<>();//保存属性相关的set方法入参类型
private final Map<String, Class<?>> getTypes = new HashMap<>();//保存属性相关的get方法返回类型
private Constructor<?> defaultConstructor;//class默认的构造函数
//记录所有属性的名称集合
private Map<String, String> caseInsensitivePropertyMap = new HashMap<>();
public Reflector(Class<?> clazz) {
//设置对应的类
type = clazz;
addDefaultConstructor(clazz);//获取clazz的默认构造函数
addGetMethods(clazz);//处理clazz中的get方法信息,填充getMethods、getTypes
addSetMethods(clazz);//处理clazz中的set方法信息,填充setMethods、setTypes
addFields(clazz);//处理没有get、set方法的属性
//根据get、set方法初始化可读属性集合和可写属性集合
readablePropertyNames = getMethods.keySet().toArray(new String[getMethods.keySet().size()]);
writeablePropertyNames = setMethods.keySet().toArray(new String[setMethods.keySet().size()]);
//初始化caseInsensitivePropertyMap
for (String propName : readablePropertyNames) {
caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName);
}
for (String propName : writeablePropertyNames) {
caseInsensitivePropertyMap.put(propName.toUpperCase(Locale.ENGLISH), propName);
}
}
//查找默认无参构造方法
private void addDefaultConstructor(Class<?> clazz) {
Constructor<?>[] consts = clazz.getDeclaredConstructors();
for (Constructor<?> constructor : consts) {
//判断是无参的构造方法
if (constructor.getParameterTypes().length == 0) {
//不能是private
if (canControlMemberAccessible()) {
try {
constructor.setAccessible(true);
} catch (Exception e) {
// Ignored. This is only a final precaution, nothing we can do.
}
}
//如果可以访问就赋值给defaultConstructor
if (constructor.isAccessible()) {
this.defaultConstructor = constructor;
}
}
}
}
//初始化getMethods和getTypes
private void addGetMethods(Class<?> cls) {
//属性与其getting方法的映射
Map<String, List<Method>> conflictingGetters = new HashMap<>();
//获取所有的方法
Method[] methods = getClassMethods(cls);
for (Method method : methods) {
//参数个数不为0说明不是getting方法
if (method.getParameterTypes().length > 0) {
continue;
}
//以get和is方法名开头
String name = method.getName();
if ((name.startsWith("get") && name.length() > 3)
|| (name.startsWith("is") && name.length() > 2)) {
//获得属性
name = PropertyNamer.methodToProperty(name);
//添加到conflictingGetters中
addMethodConflict(conflictingGetters, name, method);
}
}
//解决getting冲突方法
resolveGetterConflicts(conflictingGetters);
}
//解决getting冲突方法
private void resolveGetterConflicts(Map<String, List<Method>> conflictingGetters) {
//遍历每个属性
for (Entry<String, List<Method>> entry : conflictingGetters.entrySet()) {
//最佳的匹配方法
Method winner = null;
String propName = entry.getKey();
for (Method candidate : entry.getValue()) {
if (winner == null) {
winner = candidate;
continue;
}
//基于返回类型比较
Class<?> winnerType = winner.getReturnType();
Class<?> candidateType = candidate.getReturnType();
//如果返回类型相同
if (candidateType.equals(winnerType)) {
//说明返回了相同的值已经合并
if (!boolean.class.equals(candidateType)) {
throw new ReflectionException(
"Illegal overloaded getter method with ambiguous type for property "
+ propName + " in class " + winner.getDeclaringClass()
+ ". This breaks the JavaBeans specification and can cause unpredictable results.");
} else if (candidate.getName().startsWith("is")) {
//boolean类型的is方法
winner = candidate;
}
//不符合选择子类
} else if (candidateType.isAssignableFrom(winnerType)) {
// OK getter type is descendant
//符合选择子类
} else if (winnerType.isAssignableFrom(candidateType)) {
winner = candidate;
} else {
throw new ReflectionException(
"Illegal overloaded getter method with ambiguous type for property "
+ propName + " in class " + winner.getDeclaringClass()
+ ". This breaks the JavaBeans specification and can cause unpredictable results.");
}
}
//添加到getMethods和getTypes中
addGetMethod(propName, winner);
}
}
private void addGetMethod(String name, Method method) {
if (isValidPropertyName(name)) {
//添加到getMethods中
getMethods.put(name, new MethodInvoker(method));
Type returnType = TypeParameterResolver.resolveReturnType(method, type);
//添加到getTypes
getTypes.put(name, typeToClass(returnType));
}
}
//初始化setMethods和setTypes
private void addSetMethods(Class<?> cls) {
Map<String, List<Method>> conflictingSetters = new HashMap<>();
Method[] methods = getClassMethods(cls);
for (Method method : methods) {
String name = method.getName();
//set开头并且参数的个数为1
if (name.startsWith("set") && name.length() > 3) {
if (method.getParameterTypes().length == 1) {
name = PropertyNamer.methodToProperty(name);
addMethodConflict(conflictingSetters, name, method);
}
}
}
resolveSetterConflicts(conflictingSetters);
}
private void addMethodConflict(Map<String, List<Method>> conflictingMethods, String name, Method method) {
List<Method> list = conflictingMethods.computeIfAbsent(name, k -> new ArrayList<>());
list.add(method);
}
//解决setting方法冲突
private void resolveSetterConflicts(Map<String, List<Method>> conflictingSetters) {
for (String propName : conflictingSetters.keySet()) {
List<Method> setters = conflictingSetters.get(propName);
Class<?> getterType = getTypes.get(propName);
Method match = null;
ReflectionException exception = null;
for (Method setter : setters) {
Class<?> paramType = setter.getParameterTypes()[0];
//和getterType相同,直接使用
if (paramType.equals(getterType)) {
// should be the best match
match = setter;
break;
}
if (exception == null) {
try {
//选择一个更加匹配的
match = pickBetterSetter(match, setter, propName);
} catch (ReflectionException e) {
// there could still be the 'best match'
match = null;
exception = e;
}
}
}
if (match == null) {
throw exception;
} else {
//添加到setMethods和setTypes
addSetMethod(propName, match);
}
}
}
//寻找优先的setter
private Method pickBetterSetter(Method setter1, Method setter2, String property) {
if (setter1 == null) {
return setter2;
}
Class<?> paramType1 = setter1.getParameterTypes()[0];
Class<?> paramType2 = setter2.getParameterTypes()[0];
//选择子类的参数
if (paramType1.isAssignableFrom(paramType2)) {
return setter2;
} else if (paramType2.isAssignableFrom(paramType1)) {
return setter1;
}
throw new ReflectionException("Ambiguous setters defined for property '" + property + "' in class '"
+ setter2.getDeclaringClass() + "' with types '" + paramType1.getName() + "' and '"
+ paramType2.getName() + "'.");
}
//加入setMethod
private void addSetMethod(String name, Method method) {
if (isValidPropertyName(name)) {
setMethods.put(name, new MethodInvoker(method));
Type[] paramTypes = TypeParameterResolver.resolveParamTypes(method, type);
setTypes.put(name, typeToClass(paramTypes[0]));
}
}
//获得Type对应的类
private Class<?> typeToClass(Type src) {
Class<?> result = null;
//如果是普通类型就直接使用类
if (src instanceof Class) {
result = (Class<?>) src;
//泛型类型使用泛型
} else if (src instanceof ParameterizedType) {
result = (Class<?>) ((ParameterizedType) src).getRawType();
//泛型数组获得具体类
} else if (src instanceof GenericArrayType) {
Type componentType = ((GenericArrayType) src).getGenericComponentType();
if (componentType instanceof Class) {
result = Array.newInstance((Class<?>) componentType, 0).getClass();
} else {
Class<?> componentClass = typeToClass(componentType);
result = Array.newInstance((Class<?>) componentClass, 0).getClass();
}
}
if (result == null) {
//都不符合使用Object类
result = Object.class;
}
return result;
}
//找到field
private void addFields(Class<?> clazz) {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (canControlMemberAccessible()) {
try {
field.setAccessible(true);
} catch (Exception e) {
// Ignored. This is only a final precaution, nothing we can do.
}
}
if (field.isAccessible()) {
if (!setMethods.containsKey(field.getName())) {
int modifiers = field.getModifiers();
if (!(Modifier.isFinal(modifiers) && Modifier.isStatic(modifiers))) {
addSetField(field);//这里给没有个set方法的属性,生成一个set方法
}
}
if (!getMethods.containsKey(field.getName())) {
addGetField(field);//这里给没有个get方法的属性,生成一个get方法
}
}
}
if (clazz.getSuperclass() != null) {
addFields(clazz.getSuperclass());
}
}
//没有set方法生成一个set方法
private void addSetField(Field field) {
if (isValidPropertyName(field.getName())) {
//添加到setMethods中
setMethods.put(field.getName(), new SetFieldInvoker(field));
Type fieldType = TypeParameterResolver.resolveFieldType(field, type);
//添加到setTypes中
setTypes.put(field.getName(), typeToClass(fieldType));
}
}
//同样的没有get方法设置一个get方法
private void addGetField(Field field) {
if (isValidPropertyName(field.getName())) {
getMethods.put(field.getName(), new GetFieldInvoker(field));
Type fieldType = TypeParameterResolver.resolveFieldType(field, type);
getTypes.put(field.getName(), typeToClass(fieldType));
}
}
//是否是一个有效的成员变量名称
private boolean isValidPropertyName(String name) {
return !(name.startsWith("$") || "serialVersionUID".equals(name) || "class".equals(name));
}
//获得所有方法
private Method[] getClassMethods(Class<?> cls) {
//每个方法签名和该方法的映射
Map<String, Method> uniqueMethods = new HashMap<>();
//循环类直到父类为Object
Class<?> currentClass = cls;
while (currentClass != null && currentClass != Object.class) {
//记录当前类中的方法
addUniqueMethods(uniqueMethods, currentClass.getDeclaredMethods());
// we also need to look for interface methods -
// because the class may be abstract
Class<?>[] interfaces = currentClass.getInterfaces();
for (Class<?> anInterface : interfaces) {
//记录当前接口中的方法
addUniqueMethods(uniqueMethods, anInterface.getMethods());
}
currentClass = currentClass.getSuperclass();
}
//转成Method数组后返回
Collection<Method> methods = uniqueMethods.values();
return methods.toArray(new Method[methods.size()]);
}
private void addUniqueMethods(Map<String, Method> uniqueMethods, Method[] methods) {
for (Method currentMethod : methods) {
//忽略bridge方法,主要是泛型擦除的时候生成的
if (!currentMethod.isBridge()) {
//获得方法签名
String signature = getSignature(currentMethod);
if (!uniqueMethods.containsKey(signature)) {
if (canControlMemberAccessible()) {
try {
currentMethod.setAccessible(true);
} catch (Exception e) {
// Ignored. This is only a final precaution, nothing we can do.
}
}
// 添加到 uniqueMethods 中
uniqueMethods.put(signature, currentMethod);
}
}
}
}
//得到方法签名
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();
}
//判断是否可以修改可访问性
public static boolean canControlMemberAccessible() {
try {
SecurityManager securityManager = System.getSecurityManager();
if (null != securityManager) {
securityManager.checkPermission(new ReflectPermission("suppressAccessChecks"));
}
} catch (SecurityException e) {
return false;
}
return true;
}
public Class<?> getType() {
return type;
}
public Constructor<?> getDefaultConstructor() {
if (defaultConstructor != null) {
return defaultConstructor;
} else {
throw new ReflectionException("There is no default constructor for " + type);
}
}
public boolean hasDefaultConstructor() {
return defaultConstructor != null;
}
//通过成员变量的名称找到他的set方法
public Invoker getSetInvoker(String propertyName) {
Invoker method = setMethods.get(propertyName);
if (method == null) {
throw new ReflectionException("There is no setter for property named '" + propertyName + "' in '" + type + "'");
}
return method;
}
//通过成员变量的名称找到他的get方法
public Invoker getGetInvoker(String propertyName) {
Invoker method = getMethods.get(propertyName);
if (method == null) {
throw new ReflectionException("There is no getter for property named '" + propertyName + "' in '" + type + "'");
}
return method;
}
public Class<?> getSetterType(String propertyName) {
Class<?> clazz = setTypes.get(propertyName);
if (clazz == null) {
throw new ReflectionException("There is no setter for property named '" + propertyName + "' in '" + type + "'");
}
return clazz;
}
public Class<?> getGetterType(String propertyName) {
Class<?> clazz = getTypes.get(propertyName);
if (clazz == null) {
throw new ReflectionException("There is no getter for property named '" + propertyName + "' in '" + type + "'");
}
return clazz;
}
public String[] getGetablePropertyNames() {
return readablePropertyNames;
}
public String[] getSetablePropertyNames() {
return writeablePropertyNames;
}
public boolean hasSetter(String propertyName) {
return setMethods.keySet().contains(propertyName);
}
public boolean hasGetter(String propertyName) {
return getMethods.keySet().contains(propertyName);
}
public String findPropertyName(String name) {
return caseInsensitivePropertyMap.get(name.toUpperCase(Locale.ENGLISH));
}
}