java mybatis接口反射_Mybatis源码之美:2.4.4.统一反射操作的适配器——Invoker

Invoker接口在Mybatis中用于统一处理反射调用,包括读写属性和执行方法。它通过三种实现类:GetFieldInvoker、SetFieldInvoker和MethodInvoker分别对应属性的读取、设置和方法调用。Invoker接口的invoke方法执行反射操作,getType方法返回操作对应的类型。
摘要由CSDN通过智能技术生成

Invoker

Invoker接口的作用是统一基于反射处理方法/属性的调用方式,他是适配器模式的一种实现。

> 适配器模式(包装模式)将一个类的接口适配成用户所期待的,是的原本由于接口不兼容而不能一起工作的类可以一起工作。

在Invoker接口中定义了两个方法,invoke方法用于执行反射操作,获取响应的操作结果,getType方法用于获取方法或者属性对应的类型。

/**

* mybatis中定义的用于执行方法或者属性反射操作的类

*

* 作用是统一基于反射处理方法/属性的调用方式

*

* @author Clinton Begin

*/

public interface Invoker {

/**

* 执行反射操作

*

* @param target 方法或者属性执行的目标对象

* @param args 方法或者属性执行时依赖的参数

* @return 方法执行结果

* @throws IllegalAccessException 无访问权限

* @throws InvocationTargetException 反射执行异常

*/

Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException;

/**

* 方法或者属性对应的类型

*/

Class getType();

}

在mybatis中Invoker接口有三种实现形式:

75202b87537ddd664fd229dec2c936ab.png

GetFieldInvoker用于执行读取属性值的反射操作

GetFieldInvoker对象的构造方法需要传入一个Field属性:

private final Field field;

public GetFieldInvoker(Field field) {

this.field = field;

}

他的invoke方法,基于java的反射实现了获取指定属性值的功能:

@Override

public Object invoke(Object target, Object[] args) throws IllegalAccessException {

try {

// 基于反射获取属性值

return field.get(target);

} catch (IllegalAccessException e) {

if (Reflector.canControlMemberAccessible()) {

// 修改属性访问权限,重新获取

field.setAccessible(true);

return field.get(target);

} else {

throw e;

}

}

}

getType方法则返回对应的field属性的类型:

@Override

public Class getType() {

return field.getType();

}

SetFieldInvoker用于执行设置属性值的反射操作

SetFieldInvoker对象的构造方法也需要传入一个Field属性:

private final Field field;

public SetFieldInvoker(Field field) {

this.field = field;

}

他的invoke方法,基于java的反射实现了为指定属性设值的功能:

@Override

public Object invoke(Object target, Object[] args) throws IllegalAccessException {

try {

// 执行反射

field.set(target, args[0]);

} catch (IllegalAccessException e) {

if (Reflector.canControlMemberAccessible()) {

// 修改权限,再次执行

field.setAccessible(true);

field.set(target, args[0]);

} else {

throw e;

}

}

return null;

}

getType方法则返回对应的field属性的类型:

@Override

public Class getType() {

return field.getType();

}

MethodInvoker用于执行方法的反射操作

他的构造方法需要一个Method类型的参数,在他的构造方法中,会根据方法有无入参判断方法是getter方法还是setter方法,如果是getter方法则获取方法的返回类型赋给type属性, 如果是setter方法则获取方法的入参类型赋给type属性:

/**

* 如果方法是getter方法,则表示返回值类型

* 如果方法是setter方法,则表示入参类型

*/

private final Class type;

/**

* 方法本身

*/

private final Method method;

public MethodInvoker(Method method) {

this.method = method;

if (method.getParameterTypes().length == 1) {

// 有方法入参,表示是setter方法

type = method.getParameterTypes()[0];

} else {

// 无入参表示是getter方法

type = method.getReturnType();

}

}

他的invoke方法,基于java的反射完成方法的调用:

@Override

public Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException {

try {

// 执行方法

return method.invoke(target, args);

} catch (IllegalAccessException e) {

if (Reflector.canControlMemberAccessible()) {

// 赋予访问权限之后重试

method.setAccessible(true);

return method.invoke(target, args);

} else {

throw e;

}

}

}

getType方法则返回在构造方法中赋值的type属性的值:

@Override

public Class getType() {

return type;

}

关注我,一起学习更多知识

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值