判断一个对象是不是mybatis的mapper代理实例,反射取出其继承的接口的泛型信息

核心判断方法是

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&lt;String,Integer&gt;{}
 * 输入 [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]
复制代码

猜你喜欢

转载自juejin.im/post/7037004545246887949