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是一门静态 ...
随机推荐
- Wpf学习之路……
Wpf学习之路-- Wpf是 .net中一门做winform的技术,和传统的winform的区别在于: 1. 原来的winform就是拖控件,而wpf的控件都死自己拿标记语言(xaml ...
- JAVA加密算法系列-DESCoder
package ***; import java.security.Key; import java.security.SecureRandom; import javax.crypto.Cipher ...
- Angular2入门-数据绑定
▓▓▓▓▓▓ 大致介绍 Angular2中数据绑定的方式默认是以单向方式,数据绑定的方式可以分为: 1.属性绑定和插值表达式 组件类-> 模板 2.事件绑定:模板 -> 组件类 3.双向绑 ...
- Windows 解决mysql忘记密码怎么办?
MySQL有时候忘记密码了怎么办?我给出案例和说明!一下就解决了! Windows下的实际操作如下 1.关闭正在运行的MySQL. 2.打开DOS窗口,转到mysql\bin目录. 3.输入mysql ...
- 关于constraint的用法
1.主键约束:要对一个列加主键约束的话,这列就必须要满足的条件就是非空因为主键约束:就是对一个列进行了约束,约束为(非空.不重复)以下是代码 要对一个列加主键,列名为id,表名为emp格式为:alt ...
- 使用python发送QQ邮件
这里用到了Python的两个包来发送邮件: smtplib 和 email . Python 的 email 模块里包含了许多实用的邮件格式设置函数,可以用来创建邮件“包裹”.使用的 MIMEText ...
- 一条SQL搞定信息增益的计算
欢迎大家关注腾讯云技术社区-博客园官方主页,我们将持续在博客园为大家推荐技术精品文章哦~ 周东谕,2011年加入腾讯,现任职于腾讯互娱运营部数据中心,主要从事游戏相关的数据分析和挖掘工作. 信息增益原 ...
- 【小瑕疵】表单中的button会自动提交?
在表单中使用button标签的时候会发现,即使什么类型都没有设置,但是在点击的时候会发现,表单会自动提交 比如: 我在一个表单的button中添加一个函数,当点击这个按钮时会增加一行内容: 但是当我实 ...
- LeetCode 327. Count of Range Sum
无意看到的LeetCode新题,不算太简单,大意是给一个数组,询问多少区间和在某个[L,R]之内.首先做出前缀和,将问题转为数组中多少A[j]-A[i] (j>i)在范围内. 有一种基于归并排序 ...
- StringHelper--封转自己的字符串工具类
我们每次开发项目,都会有很多的关于字符串的处理,字符串的处理太常见了,无法避免,那么这时如果可以把常用的字符串处理封装成类,在以后的开发中应该会减少一些工作量,下面代码对一些常用的字符串处理进行了封装 ...