项目场景:
在学习mybatis源码过程中,用到了jdk动态代理,仿照写了一个小demo,发现如下问题问题描述:
如下代码抛出类型转换异常:
com.sun.proxy.
P
r
o
x
y
0
c
a
n
n
o
t
b
e
c
a
s
t
t
o
c
o
m
.
d
j
.
d
e
m
o
.
s
p
r
i
n
g
b
o
o
t
d
e
m
o
.
H
a
n
d
l
e
r
M
a
p
p
e
r
Proxy0 cannot be cast to com.dj.demo.springbootdemo.HandlerMapper
Proxy0cannotbecasttocom.dj.demo.springbootdemo.HandlerMapperProxyMapper
public class HandlerMapper {
interface ProxyMapper {
@Select(value = "select * from rs_user where id = #{id}")
List<User> getUsers();
}
public static void main(String[] args) {
InvocationHandler handler = (proxy, method, args1) -> {
Select annotation = method.getAnnotation(Select.class);
System.out.println(annotation.value());;
// 该方法要返回的结果类型
method.getGenericReturnType();
// todo 解析sql
// todo 执行sql
// todo 拼装成要返回的结果类型
return null;
};
// ProxyMapper o = (ProxyMapper)Proxy.newProxyInstance(ProxyMapper.class.getClassLoader(), new Class[]{ProxyMapper.class}, handler);
ProxyMapper o = (ProxyMapper)Proxy.newProxyInstance(ProxyMapper.class.getClassLoader(), ProxyMapper.class.getInterfaces(), handler);
o.getUsers();
}
}
原因分析:
问题处在这里: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210219085324441.png)ProxyMapper o = (ProxyMapper)Proxy.newProxyInstance(
ProxyMapper.class.getClassLoader(),
ProxyMapper.class.getInterfaces(),
handler);
ProxyMapper本来已经是最上层的的接口了,如果再用ProxyMapper.class.getInterfaces() 去获取其继承的接口,已经没有更上层的接口了,获取的数组长度为0
解决方案:
将上述代码改写成如下形式 ProxyMapper o = (ProxyMapper)Proxy.newProxyInstance(
ProxyMapper.class.getClassLoader(),
new Class[]{ProxyMapper.class},
handler);
或者
ProxyMapper o = (ProxyMapper)Proxy.newProxyInstance(
ProxyMapper.class.getClassLoader(),
((ProxyMapper) () -> null).getClass().getInterfaces()
handler);