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