核心判断方法是
Proxy.getInvocationHandler(XXXMapper) instanceof org.apache.ibatis.binding.MapperProxy
复制代码
mybatis 生成动态代理的方法在org.apache.ibatis.binding.MapperProxyFactory#newInstance()
主要是通过Proxy.newProxyInstance()
protected T newInstance(MapperProxy<T> mapperProxy) {
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}
复制代码
所以可以通过Proxy.isProxyClass()
和Proxy.getInvocationHandler(XXXMapper) instanceof MapperProxy
来判断是不是mybatis的Mapper代理实例
类、字段、方法参数上的具体泛型可以通过反射获取,获取实现的接口泛型信息用.getGenericInterfaces()
和.getActualTypeArguments()
(如果是继承,用.getGenericSuperclass()
)
/**
* 获取mybatis生成的mapper代理的mapper接口的父类的泛型信息<br>
* 如<pre>
* interface XxxMapper extends BaseMapper<String,Integer>{}
* 输入 [String.class,Integer.class]
* </pre>
* @param mapperProxy 自动注入的Mapper对象的
*/
public static Type[] getMapperProxySuperclassActualTypeArgumentClass(Object mapperProxy) {
if (!Proxy.isProxyClass(mapperProxy.getClass()) || !(Proxy.getInvocationHandler(mapperProxy) instanceof MapperProxy)) {
throw new IllegalArgumentException("Input must be Mapper proxy instance!");
}
//第一个getGenericInterfaces()获取自己写的Mapper接口
//第二个getGenericInterfaces()获取自己写的Mapper接口继承的接口
//getActualTypeArguments()获取继承的接口的泛型信息
return ((ParameterizedType) ((Class<?>) mapperProxy.getClass().getGenericInterfaces()[0]).getGenericInterfaces()[0]).getActualTypeArguments();
}
复制代码
用法如下
public interface MyLogMapper extends LogMapper<MyLog> {
int save(MyLog log);
}
复制代码
@Autowried
MyLogMapper myLogMapper;
public void test(){
System.out.println(getMapperProxySuperclassActualTypeArgumentClass(myLogMapper));
}
复制代码
输出结果是Type[]{MyLog.class}
[class com.xxx.MyLog]
复制代码