Java代理笔记
代理顾名思义,就是一个中间层,当我们要使用某个方法时,不直接调用,而是告诉代理,让代理替我们去请求方法,并返回结果。在这个过程中,我们只知道代理执行并返回给了我们操作结果,至于它有没有其他操作并不知道,但这个也无关紧要,因为不管代理在请求实际方法之前和之后做了什么,对我们都不会产生任何影响。由于代理的这个特性,可以用来进行记录日志等操作。
代理分为静态代理和动态代理。
静态代理
静态代理需要我们在调用者和具体的执行者之间创建一个代理类,其实现需要被代理的接口并持有一个此接口,具体代码如下:
接口类(被代理):
public interface Hello {
void say(String name);
}
代理类:
public class HelloProxy implements Hello {
private Hello helloImpl;
public HelloProxy() {
this.helloImpl = new HelloImpl(); // HelloImpl为一个Hello接口的一个普通实现类
}
@Override
public void say(String name) {
System.out.println("before say");
helloImpl.say(name);
System.out.println("after say");
}
}
使用的时候只需要new一个代理类赋值给接口即可:Hello hello = new HelloProxy(),之后的执行会由代理类去负责。但是这么做有一个问题就是对每个需要代理的类,都需要创建一个对应的代理类,即使代理类的逻辑都是相似的,动态代理就是解决这个问题的。
动态代理
动态代理相当于在调用者和代理类之间又增加了一个中间层,在这个中间层中完成代理类的逻辑,达到复用代码的效果。这个中间层需要实现InvocationHandler接口,并持有一个被代理的类,大致代码如下:
public class Myproxy implements InvocationHandler {
private Object target; // 被代理的类
public Myproxy(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before invoke"); // 执行代理的方法前进行的操作
Object invoke = method.invoke(target, args); // 调用执行被代理的方法
System.out.println("after invoke"); // 执行代理的方法后进行的操作
return invoke; // 返回方法执行结果
}
}
使用时,使用Proxy的静态方法获取代理类,将其强转为对应的接口,之后可以同静态代理类同样使用。
Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
其中loader为类加载器,interfaces为要代理的接口,h为之前定义的实现InvocationHandler接口的类的实例。
这个方法会返回一个代理类,其实现的要代理的接口,并持有一个实现InvocationHandler接口的实例,代理类的代码大致如下:
public final class $Proxy0 extends Proxy
implements Hello
{
public $Proxy0(InvocationHandler paramInvocationHandler) {
super(paramInvocationHandler);
}
public final String say() {
try
{
return ((String)this.h.invoke(this, m3, null));
}
catch (RuntimeException localRuntimeException)
{
throw localRuntimeException;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
}
如上代码我们可以将其强转为Hello接口,实际调用的时候会调用InvocationHandler实现类中的invoke方法,而其中就是我们实现的代理业务,当然,也包括实际的业务。
这样,对于有相同代理业务的类,我们只要实现InvocationHandler接口,在其中的invoke方法实现需要代理的业务,使用时只要使用Proxy.newProxyInstance静态方法,传入对应得参数即可得到需要的代理类,再将其强转赋值给需要的接口,即可正常使用。
Java代理笔记的更多相关文章
- Java学习笔记——动态代理
所谓动态,也就是说这个东西是可变的,或者说不是一生下来就有的.提到动态就不得不说静态,静态代理,个人觉得是指一个代理在程序中是事先写好的,不能变的,就像上一篇"Java学习笔记——RMI&q ...
- java学习笔记13--反射机制与动态代理
本文地址:http://www.cnblogs.com/archimedes/p/java-study-note13.html,转载请注明源地址. Java的反射机制 在Java运行时环境中,对于任意 ...
- 瘋耔java语言笔记
一◐ java概述 1.1 ...
- Java系列笔记(2) - Java RTTI和反射机制
目录 前言 传统的RTTI 反射 反射的实现方式 反射的性能 反射与设计模式 前言 并不是所有的Class都能在编译时明确,因此在某些情况下需要在运行时再发现和确定类型信息(比如:基于构建编程,),这 ...
- Java系列笔记(1) - Java 类加载与初始化
目录 类加载器 动态加载 链接 初始化 示例 类加载器 在了解Java的机制之前,需要先了解类在JVM(Java虚拟机)中是如何加载的,这对后面理解java其它机制将有重要作用. 每个类编译后产生一个 ...
- Java学习笔记4
Java学习笔记4 1. JDK.JRE和JVM分别是什么,区别是什么? 答: ①.JDK 是整个Java的核心,包括了Java运行环境.Java工具和Java基础类库. ②.JRE(Java Run ...
- 【转载】Java系列笔记(1) - Java 类加载与初始化
Java系列笔记(1) - Java 类加载与初始化 原文地址:http://www.cnblogs.com/zhguang/p/3154584.html 目录 类加载器 动态加载 链接 初始化 示例 ...
- JAVA自学笔记27
JAVA自学笔记27 1.类的加载 1)当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化. ①加载:就是指将class文件读入内存,并为之创 ...
- head first java读书笔记
head first java读书笔记 1. 基本信息 页数:689 阅读起止日期:20170104-20170215 2. 标签 Java入门 3. 价值 8分 4. 主题 使用面向对象的思路介绍J ...
随机推荐
- PyQt完整入门教程
1.GUI开发框架简介 19年来,一直在做Android ROM相关测试,也有了一定的积累:20年,计划把之前完整的测试方案.脚本.工具进行整合复用. 第一期计划是开发一个GUI的测试工具,近期也进行 ...
- 【面试经验分享】java面试中的那些潜规则
1.大纲 潜规则1:面试的本质不是考试,而是告诉面试官你会做什么 很多刚入行的小伙伴特别容易犯的一个错误,不清楚面试官到底想问什么,其实整个面试中面试官并没有想难道你的意思,只是想通过提问的方式来知道 ...
- R的plotmath
plotmath plotmath {grDevices}:Mathematical Annotation in R # Copyright (C) 2002-2016 The R Core Team ...
- go例子(一) 使用go语言实现linux内核中的list_head
package list 代码 package list import ( "fmt" ) // 数据接口 type ElemType interface{} // 节点 type ...
- ASP.NET WebApi实现Token验证
记录笔记,在博客园中有很多实现Token的方法,这是我看过他们学到的,然后找到适合自己的解决方案,自己无聊总结一下学习经验写下的 WebApi后端接口实现Token验证 Token是在客户端频繁向服务 ...
- 我用STM32MP1做了个疫情监控平台3—疫情监控平台实现
目录 1.前言 2.数据接口的获取 3.Qt界面的实现 4.在开发板上运行Qt程序 5.使用无线模块联网 6.代码下载 @ 1.前言 之前我使用桌面版本Qt实现了肺炎疫情监控平台:基于Qt的新冠肺炎疫 ...
- Fiddler1 简单使用
1.Fiddler下载地址:https://www.telerik.com/download/fiddler 2.Fiddler设置: Fiddler是强大的抓包工具,它的原理是以web代理服务器的形 ...
- c# 自定义含有标题的容器控件(标题背景为渐变色)
1.控件效果图 此效果图中的标题颜色.字号及字体可以在控件属性中设置.标题背景的渐变色及布局内容的背景色也可以在属性中设置. 2.实现的代码(用户控件) public partial class Uc ...
- [剑指offer]14-1.剪绳子
14-1.剪绳子 方法一 动态规划 思路:递归式为f(n)=max(f(i), f(n-i)),i=1,2,...,n-1 虽然我现在也没有彻底明白这个递归式是怎么来的,但用的时候还是要注意一下.f( ...
- 学习笔记----C语言的面向对象
2020-03-26 21:27:17 面向对象的编程语言都有一个类的概念,像Java.python等.类是对特定数据的特定操作的集合体.它包含两个范畴:数据和操作.C语言是没有类的概念的,但是 ...