代理就是为了将被代理对象增强、扩展被代理对象的功能。说到代理,分为静态和动态。静态代理就是硬编码。而一般需要的都是无侵入的代理,就是动态代理。下面讲的就是最简单的JDK原生的动态代理。
JDK动态代理常用的类和接口有Proxy、InvocationHandler,下面用伪代码来演示一下。
这是一个MyBatis的mapper,他的对象是怎么实例化的呐?他是怎么执行sql并组装返回值的?
publicinterfaceUserMapper { "select * from tb_user") (publicList<User>getUsers(); }
这里来解决第二个问题,一个接口是如何执行sql并组装返回值?
publicclassMapperHandlerimplementsInvocationHandler { privateJdbcTemplatejdbcTemplate; publicMapperHandler(JdbcTemplatejdbcTemplate) { this.jdbcTemplate=jdbcTemplate; } publicObjectinvoke(Objectproxy, Methodmethod, Object[] args) throwsThrowable { // 仅保留必要的步骤,如传参等细节不做演示Selectselect=method.getAnnotation(Select.class); String[] sqls=select.value(); Stringsql=sqls[0]; ClassresultType=method.getReturnType(); // 这里就不写jdbc了,借用JdbcTemplate来执行sqlListlist=jdbcTemplate.query(sql, newBeanPropertyRowMapper<>(resultType)); returnlist; } }
有了InvocationHandler,那么就可以用动态代理来创建代理对象,这样就产生了mapper实例。在spring环境中就可以扔到spring里。
UserMappermapper= (UserMapper) Proxy.newProxyInstance( UserMapper.class.getClassLoader(), UserMapper.class.getInterfaces(), newMapperInvocationHandler(jdbcTemplate)); mapper.getUsers();
注:上述代码为伪代码,未经过实际测试,只是讲述了一下思路。