「java代理模式推荐」代理的合作模式有哪些
今天给各位分享java代理模式推荐的知识,其中也会对代理的合作模式有哪些进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
- 1、Java程序性能优化-代理模式(6)
- 2、Java程序性能优化-代理模式(3)
- 3、Java代理的三种模式有什么?
- 4、Java程序性能优化-业务代理模式(1)[1]
- 5、Java程序性能优化-代理模式(2)
- 6、Java程序性能优化-代理模式(5)
Java程序性能优化-代理模式(6)
代理模式( )
以上代码分别生成了 种代理 并对生成的代理类进行高频率的调用 最后输出各个代理类的创建耗时 动态类类名和方法调用耗时 结果如下
createJdkProxy:
JdkProxy class:$Proxy
callJdkProxy:
createCglibProxy:
CglibProxy class:$javatuning ch proxy IDBQuery$$EnhancerByCGLIB$$b a bbf
callCglibProxy:
createJavassistDynProxy:
JavassistDynProxy class:javatuning ch proxy IDBQuery_$$_javassist_
callJavassistDynProxy:
createJavassistBytecodeDynamicProxy:
JavassistBytecodeDynamicProxy class:javatuning ch proxy IDBQueryJavaassistBytecodeProxy
callJavassistBytecodeDynamicProxy:
可以看到 JDK的动态类创建过程最快 这是因为在这个内置实现中defineClass()方法被定义为native实现 故性能高于其他几种实现 但在代理类的函数调用性能上 JDK的动态代理就不如CGLIB和Javassist的基于动态代码的代理 而Javassist的基于代理工厂的代理实现 代理的性能质量最差 甚至不如JDK的实现 在实际开发应用中 代理类的方法调用频率通常要远远高于代理类的实际生成频率(相同类的重复生成会使用cache) 故动态代理对象的方法调用性能应该作为性能的主要关注点
注意 就动态代理的方法调用性能而言 CGLIB和Javassist的基于动态代码的代理都优于JDK自带的动态代理 此外 JDK的动态代理要求代理类和真实主题都实现同一个接口 而CGLIB和Javassist没有强制要求
Hibernate中代理模式的应用
用代理模式实现延迟加载的一个经典应用就在Hibernate框架中 当Hibernate加载实体bean时 并不会一次性将数据库所有的数据都装载 默认情况下 它会采取延迟加载的机制 以提高系统的性能 Hiberante中的延迟加载主要有两种 一是属性的延迟加载 二是关联表的延时加载 这里以属性的延迟加载为例 简单阐述Hibernate是如何使用动态代理的
假定有用户模型
public class User implements java io Serializable {
private Integer id;
private String name;
private int age;
//省略getter和setter
使用以下代码 通过Hibernate加载一条User信息
public static void main(String[] args) throws SecurityException
NoSuchFieldException
IllegalArgumentException
IllegalAccessException {
//从数据库载入ID为 的用户
User u=(User)HibernateSessionFactory getSession() load(User class )
//打印类名称
System out println( Class Name: +u getClass() getName())
//打印父类名称
System out println( Super Class Name: +u getClass() getSuperclass()
getName())
//实现的所有接口
Class[] ins=u getClass() getInterfaces()
for(Class cls:ins){
System out println( interface: +cls getName())
}
System out println(u getName())
}
返回目录 Java程序性能优化 让你的Java程序更快 更稳定
编辑推荐
Java程序设计培训视频教程
J EE高级框架实战培训视频教程
J ME移动开发实战教学视频
Visual C++音频/视频技术开发与实战
Oracle索引技术
lishixinzhi/Article/program/Java/gj/201311/27829
Java程序性能优化-代理模式(3)
代理模式( )
动态代理介绍
动态代理是指在运行时 动态生成代理类 即 代理类的字节码将在运行时生成并载入当前的ClassLoader 与静态代理类相比 动态类有诸多好处 首先 不需要为真实主题写一个形式上完全一样的封装类 假如主题接口中的方法很多 为每一个接口写一个代理方法也是非常烦人的事 如果接口有变动 则真实主题和代理类都要修改 不利于系统维护 其次 使用一些动态代理的生成方法甚至可以在运行时指定代理类的执行逻辑 从而大大提升系统的灵活性
注意 动态代理使用字节码动态生成加载技术 在运行时生成并加载类
生成动态代理类的方法很多 如 JDK自带的动态代理 CGLIB Javassist或者ASM库 JDK的动态代理使用简单 它内置在JDK中 因此不需要引入第三方Jar包 但相对功能比较弱 CGLIB和Javassist都是高级的字节码生成库 总体性能比JDK自带的动态代理好 而且功能十分强大 ASM是低级的字节码生成工具 使用ASM已经近乎于在使用Java bytecode编程 对开发人员要求最高 当然 也是性能最好的一种动态代理生成工具 但ASM的使用实在过于繁琐 而且性能也没有数量级的提升 与CGLIB等高级字节码生成工具相比 ASM程序的可维护性也较差 如果不是在对性能有苛刻要求的场合 笔者还是推荐CGLIB或者Javassist
动态代理实现
以上例中的DBQueryProxy为例 使用动态代理生成动态类 替代上例中的DBQueryProxy 首先 使用JDK的动态代理生成代理对象 JDK的动态代理需要实现一个处理方法调用的Handler 用于实现代理方法的内部逻辑
public class JdkDbQeuryHandler implements InvocationHandler {
IDBQuery real=null; //主题接口
@Override
public Object invoke(Object proxy Method method Object[] args)
throws Throwable {
if(real==null)
real=new DBQuery() //如果是第一次调用 则生成真实对象
return real request() //使用真实主题完成实际的操作
}
}
以上代码实现了一个Handler 可以看到 它的内部逻辑和DBQueryProxy是类似的 在调用真实主题的方法前 先尝试生成真实主题对象 接着 需要使用这个Handler生成动态代理对象
public static IDBQuery createJdkProxy(){
IDBQuery jdkProxy = (IDBQuery) Proxy newProxyInstance(
ClassLoader getSystemClassLoader()
new Class[] { IDBQuery class }
new JdkDbQeuryHandler()) //指定Handler
return jdkProxy;
}
以上代码生成一个实现了IDBQuery接口的代理类 代理类的内部逻辑由JdkDbQeuryHandler决定 生成代理类后 由newProxyInstance()方法返回该代理类的一个实例 至此 一个完整的JDK动态代理就完成了
CGLIB和Javassist的动态代理的使用和JDK的动态代理非常类似 下面 尝试使用CGLIB生成动态代理 CGLIB也需要实现一个处理代理逻辑的切入类
public class CglibDbQueryInterceptor implements MethodInterceptor {
IDBQuery real=null;
@Override
public Object intercept(Object arg Method arg Object[] arg
MethodProxy arg ) throws Throwable {
if(real==null) //代理类的内部逻辑
//和前文中的一样
real=new DBQuery()
return real request()
}
}
返回目录 Java程序性能优化 让你的Java程序更快 更稳定
编辑推荐
Java程序设计培训视频教程
J EE高级框架实战培训视频教程
J ME移动开发实战教学视频
Visual C++音频/视频技术开发与实战
Oracle索引技术
lishixinzhi/Article/program/Java/gj/201311/27832
Java代理的三种模式有什么?
Java的三种代理模式简述
本文着重讲述三种代理模式在java代码中如何写出,为保证文章的针对性,暂且不讨论底层实现原理,具体的原理将在下一篇文章中讲述。
代理模式是什么
代理模式是一种设计模式,简单说即是在不改变源码的情况下,实现对目标对象的功能扩展。
比如有个歌手对象叫Singer,这个对象有一个唱歌方法叫sing()。
假如你希望,通过你的某种方式生产出来的歌手对象,在唱歌前后还要想观众问好和答谢,也即对目标对象Singer的sing方法进行功能扩展。
但是往往你又不能直接对源代码进行修改,可能是你希望原来的对象还保持原来的样子,又或许你提供的只是一个可插拔的插件,甚至你有可能都不知道你要对哪个目标对象进行扩展。这时就需要用到java的代理模式了。网上好多用生活中的经理人的例子来解释“代理”,看似通俗易懂,但我觉得不适合程序员去理解。程序员应该从代码的本质入手。
Java程序性能优化-业务代理模式(1)[1]
业务代理模式( )
Value Object模式是将远程调用的传递数据封装在一个串行化的对象中进行传输 而业务代理模式则是将一组由远程方法调用构成的业务流程 封装在一个位于展示层的代理类中 比如 如果用户需要修改一个订单 订单修改操作可细分为 个子操作
校验用户
获取旧的订单信息
更新订单
系统结构如图 所示
图 展示层与业务逻辑层交互示例
以上结构存在两个问题
( )当展示层存在大量并发线程时 这些线程都会直接进行远程方法调用 进而会加重网络负担
( )由于缺乏对订单修改操作流程的有效封装 如果将来修改流程发生变化 那么展示层组件需要修改
为了有效地解决以上两个问题 可以在展示层中加入业务代理对象 业务代理对象负责和远程服务器通信 完成订单修改操作 而业务代理对象本身只暴露简单的updateOrder()订单修改操作供展示层组件使用 修改后的结构如图 所示
图 业务代理模式架构图
注意 业务代理模式将一些业务流程封装在前台系统 为系统性能优化提供了基础平台 在业务代理中 不仅可以复用业务流程 还可以视情况为展示层组件提供缓存等功能 从而减少远程方法调用次数 降低系统压力
lishixinzhi/Article/program/Java/gj/201311/27810
Java程序性能优化-代理模式(2)
代理模式( )
代理模式的实现和使用
基于以上设计 IDBQuery的实现如下 它只有一个request()方法
public interface IDBQuery {
String request()
}
图 代理模式的一种实现
DBQuery实现如下 它是一个重量级对象 构造会比较慢
public class DBQuery implements IDBQuery{
public DBQuery(){
try {
Thread sleep( ) //可能包含数据库连接等耗时操作
} catch (InterruptedException e) {
e printStackTrace()
}
}
@Override
public String request() {
return request string ;
}
}
代理类DBQueryProxy是轻量级对象 创建很快 用于替代DBQuery的位置
public class DBQueryProxy implements IDBQuery {
private DBQuery real=null;
@Override
public String request() {
//在真正需要的时候 才创建真实对象 创建过程可能很慢
if(real==null)
real=new DBQuery()
//在多线程环境下 这里返回一个虚假类 类似于Future模式
return real request()
}
}
最后 主函数如下 它引用IDBQuery接口 并使用代理类工作
public class Main {
public static void main(String args[]){
IDBQuery q=new DBQueryProxy() //使用代理
q request() //在真正使用时才创建真实对象
}
}
注意 将代理模式用于实现延迟加载 可以有效地提升系统的启动速度 对改善用户体验有很大的帮助
返回目录 Java程序性能优化 让你的Java程序更快 更稳定
编辑推荐
Java程序设计培训视频教程
J EE高级框架实战培训视频教程
J ME移动开发实战教学视频
Visual C++音频/视频技术开发与实战
Oracle索引技术
lishixinzhi/Article/program/Java/gj/201311/27833
Java程序性能优化-代理模式(5)
代理模式( )
在以上代码中 使用CtField make()方法和CtNewMehod make()方法在运行时生成了代理类的字段和方法 这些逻辑由Javassist的CtClass对象处理 将Java代码转换为对应的字节码 并生成动态代理类的实例
注意 与静态代理相比 动态代理可以很大幅度地减少代码行数 并提升系统的灵活性
在Java中 动态代理类的生成主要涉及对ClassLoader的使用 这里以CGLIB为例 简要阐述动态类的加载过程 使用CGLIB生成动态代理 首先需要生成Enhancer类实例 并指定用于处理代理业务的回调类 在Enhancer create()方法中 会使用DefaultGeneratorStrategy Generate()方法生成动态代理类的字节码 并保存在byte数组中 接着使用ReflectUtils defineClass()方法 通过反射 调用ClassLoader defineClass()方法 将字节码装载到ClassLoader中 完成类的加载 最后使用ReflectUtils newInstance()方法 通过反射 生成动态类的实例 并返回该实例 无论使用何种方法生成动态代理 虽然实现细节不同 但主要逻辑都如图 所示
图 实现动态代理的基本步骤
前文介绍的几种动态代理的生成方法 性能有一定差异 为了能更好地测试它们的性能 去掉DBQuery类中的sleep()代码 并使用以下方法测试
public static final int CIRCLE= ;
public static void main(String[] args) throws Exception {
IDBQuery d=null;
long begin=System currentTimeMillis()
d=createJdkProxy() //测试JDK动态代理
System out println( createJdkProxy: +(System currentTimeMillis() beg in))
System out println( JdkProxy class: +d getClass() getName())
begin=System currentTimeMillis()
for(int i= ;iCIRCLE;i++)
d request()
System out println( callJdkProxy: +(System currentTimeMillis() begin ))
begin=System currentTimeMillis()
d=createCglibProxy() //测试CGLIB动态代理
System out println( createCglibProxy: +(System currentTimeMillis() b egin))
System out println( CglibProxy class: +d getClass() getName())
begin=System currentTimeMillis()
for(int i= ;iCIRCLE;i++)
d request()
System out println( callCglibProxy: +(System currentTimeMillis() beg in))
begin=System currentTimeMillis()
d=createJavassistDynProxy() //测试Javaassist动态代理
System out println( createJavassistDynProxy: +(System currentTimeMil lis() begin))
System out println( JavassistDynProxy class: +d getClass() getName())
begin=System currentTimeMillis()
for(int i= ;iCIRCLE;i++)
d request()
System out println( callJavassistDynProxy: +(System currentTimeMilli s() begin))
begin=System currentTimeMillis()
d=createJavassistBytecodeDynamicProxy() //测试Javassist动态代理
System out println( createJavassistBytecodeDynamicProxy: +(System cu rrentTimeMillis() begin))
System out println( JavassistBytecodeDynamicProxy class: +d getClass()
getName())
begin=System currentTimeMillis()
for(int i= ;iCIRCLE;i++)
d request()
System out println( callJavassistBytecodeDynamicProxy: +(System curr entTimeMillis() begin))
}
返回目录 Java程序性能优化 让你的Java程序更快 更稳定
编辑推荐
Java程序设计培训视频教程
J EE高级框架实战培训视频教程
J ME移动开发实战教学视频
Visual C++音频/视频技术开发与实战
Oracle索引技术
lishixinzhi/Article/program/Java/gj/201311/27830
java代理模式推荐的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于代理的合作模式有哪些、java代理模式推荐的信息别忘了在本站进行查找喔。
发布于:2022-12-29,除非注明,否则均为
原创文章,转载请注明出处。