java动态代理的2种实现方式
java的动态代理在接java的api上有说明,这里就不写了。我理解的代理:
对特定接口中特定方法的功能进行扩展,这就是代理。代理是通过代理实例关联的调用处理程序对象调用方法。
下面通过一个例子看一下:
接口:
public interface Num {
void show();
int getNum();
int getProduct(int x);
}
实现类:
public class MyNum implements Num {
@Override
public int getNum() {
return 3;
}
@Override
public int getProduct(int x) {
return x;
}
@Override
public void show() {
System.out.println("底层方法打印数字99");
}
}
先看一下Method中的invoke方法在api中是怎么描述的

就是说调用处理程序对接口的实现类对象调用Method对象表示的底层方法。
第一种实现代理的方式:
public class NumProxy {
private Object num;
//通过构造方法构造接口的实现类对象
public NumProxy(Object num) {
this.num = num;
}
public Object getNumByProxy(){
Object numProxy = Proxy.newProxyInstance(num.getClass().getClassLoader(), new Class[]{Num.class}, new InvocationHandler() {
/**
* method: 对应于在代理实例上调用的接口方法的 Method 实例。我理解的就是被代理的真实方法实例
* args: 我理解的是真实方法的参数数组
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object obj = null;
System.out.println("在方法之前开始记录");
String methodName = method.getName();
if("getProduct".equals(methodName)){
obj = method.invoke(num, args);
obj = (Integer) obj * 2;
System.out.println("proxy: getProduct()结束");
}
else if("show".equals(methodName)){
obj = method.invoke(num, args);
System.out.println("proxy: show()结束");
}
return obj;
}
});
return numProxy;
}
}
第二种实现代理的方式:通过实现InvocationHandler接口
public class NumProxyImpl implements InvocationHandler {
//这里我把接口类型具体化了, 没有写成Object
private Num num;
public NumProxyImpl(Num num){
this.num = num;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object obj = null;
String methodName = method.getName();
if("getProduct".equals(methodName)){
System.out.println("proxy: getProduct()开始");
obj = method.invoke(num, args);
obj = (Integer) obj * 2;
System.out.println("proxy: getProduct()结束");
}else if("show".equals(methodName)){
System.out.println("proxy: show()开始");
obj = method.invoke(num, args);
System.out.println("proxy: show()结束");
}
return obj;
}
}
测试代码:
public class TestNum {
public static void main(String[] args) {
//两种方式一起测试
NumProxy np = new NumProxy(new MyNum());
Num numProxy = (Num) np.getNumByProxy();
int x = numProxy.getProduct(2);
System.out.println(x);
numProxy.show();
System.out.println("----------------");
NumProxyImpl npi = new NumProxyImpl(new MyNum());
Num numPro = (Num) Proxy.newProxyInstance(Num.class.getClassLoader(), new Class[]{Num.class}, npi);
int n = numPro.getProduct(3);
System.out.println(n);
numPro.show();
}
}
控制台结果:

第二种方式有点小疑惑,不知道大家有没有,那就是并没有显示的调用NumProxyImpl中的invoke方法,可是却执行了,嗯嗯,这个自己下去看一下啊
不想麻烦的只需要记住就行了。
比如编码的处理就可以用到代理,下次写个例子。
java动态代理的2种实现方式的更多相关文章
- Java动态代理的两种实现方式:
方式一:传统的代理 package cn.hc.domain; import java.lang.reflect.InvocationHandler; import java.lang.reflect ...
- 动态代理的两种实现方式(JDK/Cglib)
=========================================== 原文链接: 动态代理的两种实现方式(JDK/Cglib) 转载请注明出处! ================== ...
- java动态代理的两种方法
动态代理,有两种情况,第一种是有接口的情况下,你可以选择为jdk自带的动态代理的方式来编写程序,但你想要为一个实在的类编写动态代理的方式的话,这时候就必须选择一些开源的lib包,如cglib包,同时还 ...
- Java动态代理的两种实现方法
注:文章转载自:https://blog.csdn.net/m0_38039437/article/details/77970633 一.代理的概念 动态代理技术是整个java技术中最重要的一个技术, ...
- Java 动态代理原理图解 (附:2种实现方式详细对比)
动态代理在 Java 中有着广泛的应用,例如:Spring AOP 面向切面编程,Hibernate 数据查询.以及 RPC Dubbo 远程调用等,都有非常多的实际应用@mikechen 目录 ...
- Java 动态代理
被代理的接口特点: 1. 不能有重复的接口,以避免动态代理类代码生成时的编译错误. 2. 这些接口对于类装载器必须可见,否则类装载器将无法链接它们,将会导致类定义失败. 3. 需被代理的所有非 pub ...
- 彻底理解JAVA动态代理
代理设计模式 定义:为其他对象提供一种代理以控制对这个对象的访问. 代理模式的结构如下图所示. 动态代理使用 java动态代理机制以巧妙的方式实现了代理模式的设计理念. 代理模式示例代码 public ...
- Java 动态代理机制分析及扩展
Java 动态代理机制分析及扩展,第 1 部分 王 忠平, 软件工程师, IBM 何 平, 软件工程师, IBM 简介: 本文通过分析 Java 动态代理的机制和特点,解读动态代理类的源代码,并且模拟 ...
- [转]Java 动态代理机制分析及扩展
引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执 ...
随机推荐
- 解决Android Studio 无法显示Layout视图问题
在Android Studio 当中,如果你选择的SDK的版本 与你所显示的视图版本不一致时,会出现这个错误 Exception raised during rendering:com/android ...
- 浅谈Java的throw与throws
转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...
- hibernate的基本xml文件配置
需要导入基本的包hibernate下的bin下的required和同bin下optional里的c3p0包下的所有jar文件,当然要导入mysql的驱动包了.下面需要注意的是hibernate的版本就 ...
- 关键帧动画:@keyframes
关键帧动画:@keyframes: <!DOCTYPE html> <html> <head> <meta charset="UTF-8" ...
- μCos-ii学习笔记1_概述
一.μCos-ii _概述 网上关于μCosii的文章多不胜数,本人学习的过程中也参考了很多人的理解和想法,看的是卢有亮老师的<嵌入式实时操作系统-μC/OS原理与实践>(第2版),同时也 ...
- 2DToolkit官方文档中文版打地鼠教程(三):Sprite Collections 精灵集合
这是2DToolkit官方文档中 Whack a Mole 打地鼠教程的译文,为了减少文中过多重复操作的翻译,以及一些无必要的句子,这里我假设你有Unity的基础知识(例如了解如何新建Sprite等) ...
- XSS 前端防火墙 —— 无懈可击的钩子
昨天尝试了一系列的可疑模块拦截试验,尽管最终的方案还存在着一些兼容性问题,但大体思路已经明确了: 静态模块:使用 MutationObserver 扫描. 动态模块:通过 API 钩子来拦截路径属性. ...
- C#委托使用详解(Delegates)
摘要 委托是C#编程一个非常重要的概念,也是一个难点.本文将系统详细讲解委托. 1. 委托是什么? 其实,我一直思考如何讲解委托,才能把委托说得更透彻.说实话,每个人都委托都有不同的见解,因为看问题的 ...
- git 使用
三个状态 文件由 git 维护三中状态 modified:文件被改动,但还没有被提交 staged:标记被改动的文件到下次需要提交的文件快照 committed:文件已经被安全保存到本地 可以使用命令 ...
- C# OracleDBhelper
引用 using System.Configuration;using System.Data.OracleClient; 连接字符串 <connectionStrings> <ad ...