动态代理工厂

  1. public class MapperProxyFactory<T> {
  2. private final Class<T> mapperInterface;
  3. public MapperProxyFactory(Class<T> mapperInterface) {
  4. this.mapperInterface = mapperInterface;
  5. }
  6. public T newInstance(Map<String,String>sqlSession){
  7. final MapperProxy<T> mapperProxy=new MapperProxy<>(sqlSession,mapperInterface);
  8. return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(),new Class[]{mapperInterface}, mapperProxy);
  9. }
  10. }

newProxyInstance,方法有三个参数:
loader: 用哪个类加载器去加载代理对象
interfaces:动态代理类需要实现的接口
h:动态代理方法在执行时,会调用h里面的invoke方法去执行

动态代理类

  1. public class MapperProxy<T> implements InvocationHandler, Serializable {
  2. private Map<String, String> sqlSession;
  3. private final Class<T> mapperInterface;
  4. public MapperProxy(Map<String, String> sqlSession, Class<T> mapperInterface) {
  5. this.sqlSession = sqlSession;
  6. this.mapperInterface = mapperInterface;
  7. }
  8. @Override
  9. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  10. if (Object.class.equals(method.getDeclaringClass())) {
  11. return method.invoke(this, args);
  12. } else {
  13. return "你的被代理了!" + sqlSession.get(mapperInterface.getName() + "." + method.getName());
  14. }
  15. }
  16. }

invoke三个参数:
proxy:就是代理对象,newProxyInstance方法的返回对象
method:调用的方法
args: 方法中的参数

调用案列

创建 接口

  1. public interface IUserDao {
  2. String queryUser(String uid);
  3. Integer detailUser(String uid);
  4. }

调用

  1. public class MpTest {
  2. @Test
  3. public void test_MapperProxyFactory() {
  4. //创建代理
  5. MapperProxyFactory<IUserDao> factory = new MapperProxyFactory<>(IUserDao.class);
  6. Map<String, String> sqlSession = new HashMap<>();
  7. sqlSession.put("cn.wh.dao.IUserDao.queryUser", "模拟执行 Mapper.xml 中 SQL 语句的操作:查询用户姓名");
  8. sqlSession.put("cn.bugstack.mybatis.test.dao.IUserDao.queryUserName", "模拟执行 Mapper.xml 中 SQL 语句的操作:查询用户年龄");
  9. IUserDao userDao = factory.newInstance(sqlSession);
  10. //调用方法
  11. String res = userDao.queryUser("10001");
  12. System.out.println(res);
  13. }
  14. }