java有关静态代理及动态代理的实现
引言:
代理是基本的设计模式之一,它为你提供额外的或不同的操作而插入的用来代替实际对象的对象(委托对象)。这些对象通常涉及到与实际对象的通信,因此代理通常充当中间人的角色。--JAVA编程思想
相关的类和接口
要了解 Java 动态代理的机制,首先需要了解以下相关的类或接口:
- java.lang.reflect.Proxy:这是 Java 动态代理机制的主类,它提供了一组静态方法来为一组接口动态地生成代理类及其对象。
清单 1. Proxy 的静态方法
123456789101112// 方法 1: 该方法用于获取指定代理对象所关联的调用处理器
static InvocationHandler getInvocationHandler(Object proxy)
// 方法 2:该方法用于获取关联于指定类装载器和一组接口的动态代理类的类对象
static Class getProxyClass(ClassLoader loader, Class[] interfaces)
// 方法 3:该方法用于判断指定类对象是否是一个动态代理类
static boolean isProxyClass(Class cl)
// 方法 4:该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例
static Object newProxyInstance(ClassLoader loader, Class[] interfaces,
InvocationHandler h)
- java.lang.reflect.InvocationHandler:这是调用处理器接口,它自定义了一个 invoke 方法,用于集中处理在动态代理类对象上的方法调用,通常在该方法中实现对委托类的代理访问。
清单 2. InvocationHandler 的核心方法
123// 该方法负责集中处理动态代理类上的所有方法调用。第一个参数既是代理类实例,第二个参数是被调用的方法对象
// 第三个方法是调用参数。调用处理器根据这三个参数进行预处理或分派到委托类实例上发射执行
Object invoke(Object proxy, Method method, Object[] args)
每次生成动态代理类对象时都需要指定一个实现了该接口的调用处理器对象(参见 Proxy 静态方法 4 的第三个参数)。
- java.lang.ClassLoader:这是类装载器类,负责将类的字节码装载到 Java 虚拟机(JVM)中并为其定义类对象,然后该类才能被使用。Proxy 静态方法生成动态代理类同样需要通过类装载器来进行装载才能使用,它与普通类的唯一区别就是其字节码是由 JVM 在运行时动态生成的而非预存在于任何一个 .class 文件中。
每次生成动态代理类对象时都需要指定一个类装载器对象(参见 Proxy 静态方法 4 的第一个参数)
这里有几点需要重点强调一下:
- 从定义的方法可以看出代理类的出现是为了更加灵活的控制委托类方法的调用,而且做到无倾入;最终实现了一部分自己的逻辑后还是会调用委托类的方法调用,只不过在委托类调用之前或之后多了种控制
- 未指定代理类的非限定名称。但是,以字符串
"$Proxy"
开头的类名空间应该为代理类保留 static Object newProxyInstance(ClassLoader loader, Class[] interfaces,
InvocationHandler h)该生成的动态代理类实例中,类装载器需要说明的是它和静态代理的区别,静态代理是编译阶段实现已经确定的代理类的.class文件已经生成。但动态代理是字节码是由JVM在运行态动态生成的。
以下是笔者实现的代码DEMO;供参考:
/**
*先是静态代理
*/
public interface MyInterface { void doSomeThing(); void someThingElse(String param);
}
public class RealObject implements MyInterface{ @Override
public void doSomeThing() {
// TODO Auto-generated method stub
print("开始调用doSomeThing方法"); } @Override
public void someThingElse(String param) {
// TODO Auto-generated method stub
print("开始调用somethingelse 方法;参数"+param); } }
public class SimpleProxy implements MyInterface{ private MyInterface myInterface; public SimpleProxy(MyInterface myInterface) {
this.myInterface=myInterface;
} @Override
public void doSomeThing() {
// TODO Auto-generated method stub
print("业务逻辑dosomething...");
myInterface.doSomeThing(); } @Override
public void someThingElse(String param) {
// TODO Auto-generated method stub
print("业务逻辑ELse...");
myInterface.someThingElse(param); } public static void consumer(MyInterface myInterface) { myInterface.doSomeThing();
myInterface.someThingElse("bubu..");
} public static void main(String[] args) {
consumer(new RealObject());
consumer(new SimpleProxy(new RealObject()));
} }
/**
*动态代理
*/
自定义一个调用处理器:
/**
* 调用处理器<P>
* 动态代理能把所有调用都重定向到调用处理器上
*/
public class DynamicProxyHandle implements InvocationHandler{ private Object proxied; public DynamicProxyHandle(Object object) {
this.proxied=object;
} @Override
public Object invoke(Object proxy,Method method,Object[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
print("proxy class:"+proxy.getClass()+" method:"+method+" args:"+args); if(method.getName().equals("doSomeThing")) {
print("代理检测到doSomeThing被调用");
}
// if(args!=null) {
// for(Object object:args) {
// print("====="+object);
// }
// } return method.invoke(proxied, args);
} }
public class SimpleDynamicProxy { public static void consumer(MyInterface myInterface) { myInterface.doSomeThing();
myInterface.someThingElse("bubu..");
} public static void main(String[] args) {
RealObject realObject = new RealObject(); consumer(realObject);
print("-----------------------------------------");
/**
* 1.一个类加载器【你通常可以从已经被加载的类对象中获取得到其类加载器,然后传递给它】
* 2.希望该代理实现的接口列表【不是类或抽象类】
* 3.以及InvocationHandler的一个实现(一个调用处理器)
*/
MyInterface dynamicProxy = (MyInterface) Proxy.newProxyInstance(MyInterface.class.getClassLoader(),
new Class[]{MyInterface.class}, new DynamicProxyHandle(realObject));
consumer(dynamicProxy); }
}
java有关静态代理及动态代理的实现的更多相关文章
- java静态代理与动态代理
原文链接:http://www.orlion.ga/207/ 一.代理模式 代理模式是经常用到的设计模式,代理模式是给指定对象提供代理对象.由代理对象来控制具体对象的引用. 代理模式涉及到的角色: 抽 ...
- java的静态代理和动态代理(jdk、cglib)
一.代理模式 代理的概念来自于设计模式中的代理模式,先了解一下代理模式 1.结构图 2.参与者 Subject:接口,定义代理类和实际类的共用接口 RealSubject:实际类,实现Subject这 ...
- 【Java】代处理?代理模式 - 静态代理,动态代理
>不用代理 有时候,我希望在一些方法前后都打印一些日志,于是有了如下代码. 这是一个处理float类型加法的方法,我想在调用它前打印一下参数,调用后打印下计算结果.(至于为什么不直接用+号运算, ...
- Java:静态代理 and 动态代理
代理模式是常用的设计模式,其特征是代理类与委托类具有相同的接口,在具体实现上,有静态代理和动态代理之分.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并 ...
- Java基础-静态代理与动态代理比较
JAVA的静态代理与动态代理比较 静态代理类: 由程序员创建或由特定工具自动生成源代码,再对其编译.在程序运行前,代理类的.class文件就已经存在了.动态代理类: 在程序运行时,运用反射机制动态创建 ...
- java中静态代理,动态代理知识的补充
文章转载自:http://blog.csdn.net/jialinqiang/article/details/8950989 一.Java动态代理 相对于静态代理的代理类在编译时生成(.class文件 ...
- java静态代理与动态代理简单分析
原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/5860749.html 1.动态代理(Dynamic Proxy) 代理分为静态代理和动态代理 ...
- 黑马程序员:Java基础总结----静态代理模式&动态代理
黑马程序员:Java基础总结 静态代理模式&动态代理 ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 静态代理模式 public class Ts { ...
- Java静态代理和动态代理
今天介绍一下代理设计模式,在业务场景中使用代理模式的好处有很多,包括什么权限校验,事务管理等等,具体有什么好处大家自动百度吧,我这里只解释代理模式的设计原理.首先这个设计模式出来的时候先是静态代理模式 ...
- java中的静态代理和动态代理,入门整理
静态代理和动态代理主要解决的问题是:在直接访问对象时带来的问题,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后 ...
随机推荐
- 第13.3节 图形界面开发tkinter
一. 引言 老猿最开始是准备就tkinter单独开一个章节,但学了一段时间tkinter,最后放弃了,前一阵子还准备干脆不介绍相关的内容.主要原因有三个,一是tkinter没有界面设计的工具,所有界面 ...
- hihocoder 1489(微软2017, 数学,模拟)
题目链接:http://hihocoder.com/problemset/problem/1489?sid=1587434 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 ...
- Scrum冲刺_Day04
一.团队展示: 1.项目:light_note备忘录 2.队名:删库跑路队 3.团队成员 队员(不分先后) 项目角色 黄敦鸿 后端工程师.测试 黄华 后端工程师.测试 黄骏鹏 后端工程师.测试 黄源钦 ...
- 别再说你不懂什么是API了
API 全称 Application Programming Interface, 即应用程序编程接口. 看到这里,急性子的小白同学马上就憋不住了:这不管是英文还是中文我每个字都懂啊,只是凑一块就不知 ...
- 部署在GitHub的个人博客如何绑定个人域名
前提是已经搭建好了自己的个人博客 如果想要搭建自己的个人博客可以来我的个人博客学习呀 地址 购买域名 首先想要绑定域名,总归需要去购买一个属于自己的域名吧,我是在腾讯云上面购买的域名(不是广告) 在腾 ...
- Android 11 源码下载+编译教程
下载AOSP源码 这里我使用的是外国语大学的镜像执行的下载,Mac系统的话,一定要在区分大小姐的磁盘下执行 repo init -u https://mirrors.bfsu.edu.cn/git/A ...
- HTTP/2做错了什么?刚刚辉煌2年就要被弃用了!?
GitHub 19k Star 的Java工程师成神之路,不来了解一下吗! GitHub 19k Star 的Java工程师成神之路,真的不来了解一下吗! GitHub 19k Star 的Java工 ...
- jwt 简单基本使用加密解密
import jwt # 加密 encode_jwt=jwt.encode({'uid':'123'},'密钥123',algorithm='HS256') print(encode_jwt) # 解 ...
- SpringBoot + SpringSecurity + Mybatis-Plus + JWT + Redis 实现分布式系统认证和授权(刷新Token和Token黑名单)
1. 前提 本文在基于SpringBoot整合SpringSecurity实现JWT的前提中添加刷新Token以及添加Token黑名单.在浏览之前,请查看博客: SpringBoot + Sp ...
- dataframe,list,numpy之间的互相转换
dataframe,numpy,list之间的互相转换 由于目前学校要做一些数据分析处理的作业有要用到dataframe,list,numpy之间的转化,所以在此总结一下这些用法. dataframe ...