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是一门静态 ...
随机推荐
- Android下使用busybox的ifconfig
busybox ifconfig eth0 10.0.16.45 netmask 255.255.254.0 broadcast 10.0.16.186busybox route add defaul ...
- Git与Github的使用学习
摘要 本文讲解下Git的使用,包括使用Git上传项目工程到Github,文末有彩蛋哦. 1.安装Git 使用apt-get安 sudo apt-get update sudo apt-get inst ...
- HTML基础学习(一)—HTML
一.HTML的介绍 HTML(HyperText Markup Language)超文本标记语言,不是一种编程语言,而是一种描述性的标记语言,用于描述超文本的内容的显示,比如字体颜色或者大小 ...
- jmeter参数化随机取值实现
jmeter能用来做参数化的组件有几个,但是都没有随机取值的功能,遇到随机取值的需求怎么办呢? 突发奇想,可以用函数__CSVRead()来实现: __CSVRead() CSV file to ge ...
- 1164: 零起点学算法71——C语言合法标识符(存在问题)
1164: 零起点学算法71——C语言合法标识符 Time Limit: 1 Sec Memory Limit: 64 MB 64bit IO Format: %lldSubmitted: 10 ...
- java 基础知识八 正则表达式
java 基础知识八 正则表达式 正则表达式是一种可以用于模式匹配和替换的规范,一个正则表达式就是由普通的字符(例如字符a到z)以及特殊字符(元字符)组成的文字模式,它 用以描述在查找文字主体时待 ...
- windows下nginx的安装及使用方法入门
nginx功能之一可以启动一个本地服务器,通过配置server_name和root目录等来访问目标文件 一. 下载 http://nginx.org/ 下载后解压 二. 修改配置文件 ngin ...
- 关于sql语句between and的边界问题
BETWEEN 操作符 操作符 BETWEEN ... AND 会选取介于两个值之间的数据范围.这些值可以是数值.文本或者日期. SQL BETWEEN 语法 SELECT column_name(s ...
- 关于 __proto__和prototype的一些理解
var Person = function(name) {}; Person.prototype.say = function() { console.log("Person say&quo ...
- java上转型和下转型(对象的多态性)
/*上转型和下转型(对象的多态性) *上转型:是子类对象由父类引用,格式:parent p=new son *也就是说,想要上转型的前提必须是有继承关系的两个类. *在调用方法的时候,上转型对象只能调 ...