Java反射机制剖析(三)-简单谈谈动态代理
通过Java反射机制剖析(一)和Java反射机制剖析(二)的学习,已经对反射有了一定的了解,这一篇通过动态代理的例子来进一步学习反射机制。
1. 代理模式
代理模式就是为其他对象提供一种代理来控制对这个对象的访问。其实代理模式是在访问的对象时引入一定程度的间接性,这种间接性可以附加多种用途。
它 的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会 存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
2. 分类
代理类按照创建时期可以分为两种,静态代理类和动态代理类。
静态代理类:由程序员创建或由特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
动态代理类:在程序运行时,运用反射机制动态创建而成。
3. 静态代理和动态代理举例
静态代理:
业务接口类:
package com.bjpowernode.pattern; public interface UserManager { public void addUser(String userId, String userName); public void delUser(String userId); public void modifyUser(String userId, String userName); public String findUser(String userId);
}
业务接口实现类:
package com.bjpowernode.pattern; public class UserManagerImpl implements UserManager { public void addUser(String userId, String userName) {
//System.out.println("start-->>addUser() userId-->>" + userId);
try {
System.out.println("UserManagerImpl.addUser() userId-->>" + userId); //System.out.println("success-->>addUser()");
}catch(Exception e) {
e.printStackTrace();
//System.out.println("error-->>addUser()");
throw new RuntimeException();
}
} public void delUser(String userId) {
System.out.println("UserManagerImpl.delUser() userId-->>" + userId);
} public String findUser(String userId) {
System.out.println("UserManagerImpl.findUser() userId-->>" + userId);
return "张三";
} public void modifyUser(String userId, String userName) {
System.out.println("UserManagerImpl.modifyUser() userId-->>" + userId);
} }
业务代理类:
package com.bjpowernode.pattern; public class UserManagerImplProxy implements UserManager { private UserManager userManager; public UserManagerImplProxy(UserManager userManager) {
this.userManager = userManager;
} public void addUser(String userId, String userName) {
try {
System.out.println("start-->>addUser() userId-->>" + userId);
userManager.addUser(userId, userName);
System.out.println("success-->>addUser()");
}catch(Exception e) {
e.printStackTrace();
System.out.println("error-->>addUser()");
}
} public void delUser(String userId) { } public String findUser(String userId) {
return null;
} public void modifyUser(String userId, String userName) { } }
客户端类:
package com.bjpowernode.pattern; public class Client { /**
* @param args
*/
public static void main(String[] args) {
//UserManager userManager = new UserManagerImpl();
UserManager userManager = new UserManagerImplProxy(new UserManagerImpl());
userManager.addUser("0001", "张三");
} }
运行结果:
start-->>addUser() userId-->>0001
UserManagerImpl.addUser() userId-->>0001
success-->>addUser()
动态代理:
业务接口类:
package com.bjpowernode.pattern; public interface UserManager { public String test(String userId);
}
业务接口实现类:
package com.bjpowernode.pattern; public class UserManagerImpl implements UserManager { public String test(String userId) {
System.out.println("UserManagerImpl.findUser() userId-->>" + userId);
return "张三";
} }
BusinessHandler类:
package com.bjpowernode.pattern; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class BusinessHandler implements InvocationHandler { private Object targetObject; public Object newProxyInstance(Object targetObject) { this.targetObject = targetObject;
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(), this);
} public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("start-->>" + method.getName());
for (int i=0; i<args.length; i++) {
System.out.println(args[i]);
}
Object ret = null;
try {
//调用目标方法
ret = method.invoke(targetObject, args);
System.out.println("success-->>" + method.getName());
}catch(Exception e) {
e.printStackTrace();
System.out.println("error-->>" + method.getName());
throw e;
}
return ret;
} }
客户端类:
package com.bjpowernode.pattern; import java.lang.reflect.Field; public class Client { /**
* @param args
*/
public static void main(String[] args) { BusinessHandler businessHandler = new BusinessHandler();
UserManager userManager = (UserManager)businessHandler.newProxyInstance(new UserManagerImpl()); //userManager.addUser("0001", "张三");
//userManager.delUser("0001");
// System.out.println(userManager.getClass().getName()); String name = userManager.test("0001");
//String name = ((UserManagerImpl) logHandler.newProxyInstance(new UserManagerImpl())).test("0001");
System.out.println("Client.main() --- " + name);
} }
结果
start-->>test
0001
UserManagerImpl.findUser() userId-->>0001
success-->>test
Client.main() --- 张三
Java反射机制剖析(三)-简单谈谈动态代理的更多相关文章
- Java反射机制(四):动态代理
一.静态代理 在开始去学习反射实现的动态代理前,我们先需要了解代理设计模式,那何为代理呢? 代理模式: 为其他对象提供一种代理,以控制对这个对象的访问. 先看一张代理模式的结构图: 简单的理解代理设计 ...
- Java反射机制剖析(四)-深度剖析动态代理原理及总结
动态代理类原理(示例代码参见java反射机制剖析(三)) a) 理解上面的动态代理示例流程 a) 理解上面的动态代理示例流程 b) 代理接口实现类源代码剖析 咱们一起来剖析一下代理实现类($Pr ...
- Java反射机制剖析(一)-定义和API
1. 什么是Java反射机制 Java的反射机制是在程序运行时,能够完全知道任何一个类,及其它的属性和方法,并且能够任意调用一个对象的属性和方法.这种运行时的动态获取就是Java的反射机制.其 ...
- Java反射机制剖析(二)-功能以及举例
从<java反射机制剖析(一)>的API我们看到了许多接口和类,我们能够通过这些接口做些什么呢? 从上篇API中我们能看到它能够完成下面的这些功能: 1) 获得类 A. 运 ...
- java反射机制剖析(二)— Class Loader
上一篇博客简要的提了一下java反射机制中涉及到的一些相关知识,那么ClassLoader就是当中之中的一个.本篇博客就具体的对ClassLoader做一个相对深入的了解. 作为了解须要知道的是.事实 ...
- 【54】Java反射机制剖析
java反射机制: 1.指的是可以于运行时加载,探知和使用编译期间完全未知的类. 2.程序在运行状态中, 可以动态加载一个只有名称的类, 对于任意一个已经加载的类,都能够知道这个类的所有属性和方法; ...
- JAVA反射机制--静态加载与动态加载
Java反射是Java被视为动态(或准动态)语言的一个关键性质.这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如pu ...
- Java反射机制(三):调用对象的私有属性和方法
一. 通过反射调用类中的方法 在正常情况下,得到类的对象后,我们就可以直接调用类中的方法了,如果要想调用的话,则肯定必须清楚地知道要调用的方法是什么,之后通过Class类中的getMethod方法,可 ...
- Java反射机制深度剖析
版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! Java反射机制是Java语言中一种很重要的机制,可能在工作中用到的机会不多,但是在很多框架中都有用到这种机制.我们知道Java是一门静态 ...
随机推荐
- 【 js 基础 】 深浅拷贝
underscore的源码中,有很多地方用到了 Array.prototype.slice() 方法,但是并没有传参,实际上只是为了返回数组的副本,例如 underscore 中 clone 的方法: ...
- 发散问题——Spring容器及加载
一.前言 发散问题系列,是围绕日常工作,发散思考,提取问题,并寻求答案的一个系列.总的来说,就是将遇到的问题发散来提出更多的问题,并通过解决发散问题,从而对问题有更深入的了解,对知识有更深刻的记忆,帮 ...
- 第一个SignalR案例
说明:开发的案例为Hub(集线器) 一.开发环境 VS2013 ,window10 二.步骤 打开vs创建一个新的解决方案,添加一个空的WebForm项目. 使用NuGet添加引用.命令:PM> ...
- 【卸载】oracle卸载
Oracle卸载比较麻烦,不能简单卸载就完成了,有时没有卸载完整,下次安装不能很好的安装: 当然Oracle卸载也没有那么难,只是步骤比较多.Oracle10g还是Oracle11g卸载步骤都是一样的 ...
- Html5-audio标签简介及手机端不自动播放问题
1.audio:html5音频标签 <audio loop src="/photo/aa.mp3" id="audio" autoplay preload ...
- 读书笔记 effective c++ Item 27 尽量少使用转型(casting)
C++设计的规则是用来保证使类型相关的错误不再可能出现.理论上来说,如果你的程序能够很干净的通过编译,它就不会尝试在任何对象上执行任何不安全或无意义的操作.这个保证很有价值,不要轻易放弃它. 不幸的是 ...
- commitProperties方法
自定义的组件,如果重写commitProperties方法,那么在该方法内部一定要注意super.commitProperties()的调用.
- Vim常用操作-快速删除括号中内容。
如果你和我一样,希望拥有众多工具,发挥工具最大执行效率,让工作事半功倍的话,我推荐你来使用下 Vim. 刚接触Vim 会觉得它的学习曲线非常陡峭,要记住很多命令,操作太复杂.所以这个系列的分享,不会教 ...
- bootstrap快速入门笔记(九)-响应式工具
一,可用的类 超小屏幕手机 (<768px) 小屏幕平板 (≥768px) 中等屏幕桌面 (≥992px) 大屏幕桌面 (≥1200px) .visible-xs-* 可见 隐藏 隐藏 隐藏 ...
- [Git]06 如何提交空目录
git和 svn不同,仅仅跟踪文件的变动,不跟踪目录.所以,一个空目录,如果里面没有文件,即便 git add 这个目录,另外在别处 check out 的时候,是没有这个空目录的. 只跟踪文件 ...