java动态代理框架
2024-09-03 09:48:51
java动态代理是一个挺有意思的东西,他有时候可以被使用的很灵活。像rpc的调用,调用方只是定义的一个接口,动态代理让他匹配上对应的不同接口;mybatis内部的实现,编码时,只是实现了mapper层的接口和sql的xml的配置,动态代理把他们连起来。记得之前在一家公司,他们使用thrift做rpc的解决方案,每个项目都得管理thrift的连接和关闭,代码考来考去,在spring下还得不断new对象。后来参照mybatis的实现方式,使用动态代理,做成spring注入的方式,方便很多,程序员只需要加些配置就好了。
先来一个动态代理的简单实例:
/**
* Created by sten on 7/12/16.
*/
public interface Person { void eat() ;
} /**
* Created by sten on 7/12/16.
*/
public class Chinese implements Person { @Override
public void eat() {
System.out.print("eat fish.");
}
} /**
* Created by sten on 7/12/16.
*/
public class InvocationTest implements InvocationHandler { private Person person ; public InvocationTest(Person person) {
this.person = person ;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(person, args);
}
} /**
* Created by sten on 7/12/16.
*/
public class Main { public static void main(String[] args) { Chinese chinese = new Chinese() ; Person person = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(),
new Class[]{Person.class},
new InvocationTest(chinese)); person.eat();
} }
这是一般动态代理的范式,Chinese代理Person的实现,接口person每个方法的调用,实际执行的方法是InvocationTest.invoke, 当然,还有动态代理还有其他实现方式。
这里实现简单实现下mybatis的动态代理:
假设解析完mapper和xml,知道每个mapper的方法对应的sql了,通过类名和方法名,就可以执行sql
/**
* Created by sten on 7/12/16.
*/
public class SqlMap { private Map<String, String> map = new HashedMap() ; public SqlMap() {
map.put("Class1.method1","select sql1") ;
map.put("Class1.method2","delete sql1") ;
map.put("Class1.method3","update sql1") ;
map.put("Class1.method4","insert sql1") ;
map.put("Class2.method1","select sql2") ;
map.put("Class2.method2","delete sql2") ;
map.put("Class2.method3","update sql2") ;
map.put("Class2.method4","insert sql2") ;
} public String getSql(String classNameMethodName) {
return map.get(classNameMethodName) ;
} }
假设定义的一个mapper
/**
* Created by sten on 7/12/16.
*/
public interface Class1 { String method1() ; String method2() ; String method3() ; String method4() ;
}
InvocationHandler的实现
/**
* Created by sten on 7/12/16.
*/
public class InvocationSql implements InvocationHandler { private Class interfaceObject ; private SqlMap sqlMap ; public InvocationSql(Class interfaceObject, SqlMap sqlMap) {
this.interfaceObject = interfaceObject ;
this.sqlMap = sqlMap ;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String key = interfaceObject.getClass().getName() + "." + method.getName() ;
String value = sqlMap.getSql(key) ; return value ;
}
}
根据mapper接口生成对象
/**
* Created by sten on 7/12/16.
*/
public class TargetProxy<T> { public T getTarget(Class<T> interfaceObject, SqlMap sqlMap) { InvocationSql invocationSql = new InvocationSql(interfaceObject, sqlMap) ; return (T)newProxyInstance(interfaceObject.getClassLoader(),new Class[] {interfaceObject},
invocationSql) ;
} }
执行生成的对象
/**
* Created by sten on 7/12/16.
*/
public class Bitis { public static void main(String[] args) { TargetProxy targetProxy = new TargetProxy() ; Class1 class1 = (Class1) targetProxy.getTarget(Class1.class, new SqlMap()); class1.method1() ;
} }
最新文章
- 开始学nodejs —— 调试篇
- ORCALE复制表结构
- javascript --- 设计模式之构造函数模式
- SRS(simple-rtmp-server)
- 删除重复的字符(给一个字符串,删除连续重复的字符,要求时间复杂度为O(1)……)
- luarocks install with lua5.1 and luajit to install lapis
- jquery中each()函数
- go语言值得学习的开源项目推荐
- ios-王云鹤 把UIdatePicker 嵌入到 UIActionSheet中
- 清明培训 清北学堂 DAY1
- Fundebug能够捕获这些BUG
- 大数据及Hadoop的概述
- 15个最佳的 JavaScript 表单验证库
- Win10安装CAD2006
- javascript的常用事件
- .NET中制做对象的副本(二)继承对象之间的数据拷贝
- redhat vim编辑器永久添加行号及搜索
- ELK 日志查询分析nginx日志
- Dapper 嵌套对象查询
- react篇章-React State(状态)-组件都是真正隔离的
热门文章
- KMP --关于cogs1570 乌力波
- fzu1704(高斯消元法解异或方程组+高精度输出)
- [CF707D]Persistent Bookcase_主席树_bitset
- confluence导出PDF格式文件不显示中文解决
- mysql非主键提示key2 检查索引是否设定为唯一
- 编写shell脚本实现对虚拟机cpu、内存、磁盘监控机制
- (十二)springMvc 处理图片,视频等文件的上传
- 【模板】C++高精度加法
- redis键空间通知(keyspace notification)
- Java基础之IO和NIO补完