我必须得将mapper作为参数来进行传递,在进行反射调用方法的时候,就会报错。请问这种情况我该如何处理,才能够实现这一要求了?
@Configuration
@EnableScheduling
public class aaa {
// Mapper是个接口
@Autowired
private TestMapper testpMapper;
@Scheduled(cron = "0/5 * * * * ?")
private void createOrderTableTime() {
// try {
// determineCreateTable((Class<? extends BaseMapper>) Class.forName(testMapper.getClass().getName()));
determineCreateTable(testMapper.getClass());
// } catch (ClassNotFoundException e) {
// e.printStackTrace();
// }
}
// public void determineCreateTable(Class<? extends BaseMapper> tableMapper) {
public void determineCreateTable(Class tableMapper) {
try {
Method method = tableMapper.getDeclaredMethod("count", String.class);
// 这种是可行的
// int count = (int) method.invoke(testMapper, "100001");
// int count = (int) method.invoke(tableMapper, "100001");
// 在进行实例化的时候会产生错误
int count = (int) method.invoke(tableMapper.newInstance(), "100001");
System.out.println(count);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
}
}
}
报错信息如下:
java.lang.IllegalArgumentException: object is not an instance of declaring class
java.lang.InstantiationException: com.sun.proxy.$Proxy88
注入的TestMapper对象,是mybates通过JDK动态代理实现的,JDK动态代理出来的类不支持这种newInstance()的方式。
mybatis不像spring可以通过配置进行cglib代理,cglib是支持代理出来的类支持newInstance()的方式。若要做到这种,建议创建一个BaseMapper接口。里面定义你要动态调用的方法。然后所有Mapper实现此Mapper。希望对你有帮助。
public void determineCreateTable(TestMapper tableMapper)
把Class换成TestMapper即可
int count = (int) method.invoke(tableMapper.newInstance(), "100001");
你到底希望是创建mapper对象还是调用count方法,这里写混在一起了。要分开写