主要自己用动态代理模拟了为什么接口能直接调用方法。与此同时参考了其他资料,补充给出了源码在动态代理过程中的一些其他元素
接口:
public interface ICommand {
public List<Command> queryCommandList();
}
SqlSession:
public class SqlSession{
public<T> T getMapper(Class<T> c){
System.out.println("通过接口的Class从代理工厂Map取出对应的代理工厂");
System.out.println("通过代理工厂实例化一个代理类");
System.out.println("用这个代理类生成一个代理实例返回出去");
InvocationHandler handler=new MapperProxy();
return (T)Proxy.newProxyInstance(c.getClassLoader(),new Class[]{c}, handler);
}
}
MapperProxy:
public class MapperProxy implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("通过接口与method获取对应的配置文件中的信息:");
System.out.println("接口名称.方法名==namespace.id");
System.out.println("通过配置文件中的信息获取SQL语句的类型");
System.out.println("根据SQL语句类型调用sqlSession对应的增删改查方法");
System.out.println("当SQL语句类型是查询时");
System.out.println("根据返回值的类型是List、Map、Object");
System.out.println("分别调用selectList、selectMap、selectOne方法");
List<Object> list =Arrays.asList(new Object[]{"hello","world"});
return list;
}
}
测试类:
public class Test {
public static void main(String[] args) {
System.out.println("加载配置信息……");
System.out.println("通过加载配置信息加载一个代理工厂Map:");
System.out.println("这个Map存放的是接口Class与对应的代理工厂");
SqlSession sqlSession=new SqlSession();
ICommand icommand=sqlSession.getMapper(ICommand.class);
List<Command> queryCommandList = icommand.queryCommandList();
System.out.println(queryCommandList.toString());
}
}