java动态代理、Proxy与InvocationHandler
看了好多关于代理的文章,理解和整理一下。
1、代理的基本构成
抽象角色:声明真实对象和代理对象的共同接口,这样可在任何使用真实对象的地方都可以使用代理对象。
代理角色:代理对象内部含有真实对象的引用,从而可以在任何时候操作真实对象。代理对象提供一个与真实对象相同的接口,以便可以在任何时候替代真实对象。代理对象通常在客户端调用传递给真实对象之前或之后,执行某个操作,而不是单纯地将调用传递给真实对象,同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
真实角色:即为代理对象所代表的目标对象,代理角色所代表的真实对象,是我们最终要引用的对象。
下图有三种角色:Subject抽象角色、RealSubject真实角色、Proxy代理角色。其中:Subject角色负责定义RealSubject和Proxy角色应该实现的接口;RealSubject角色用来真正完成业务服务功能;Proxy角色负责将自身的request请求,调用RealSubject对应的request功能来实现业务功能,自己不真正做业务。
2、静态代理
interface Subject//抽象角色
{
public void doSomething();
}
class RealSubject implements Subject//真实角色
{
public void doSomething()
{
System.out.println( "call doSomething()" );
}
}
class SubjectProxy implements Subject//代理角色
{
//代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。
Subject subimpl = new RealSubject();
public void doSomething()
{
System.out.println("before"); //调用目标对象之前可以做相关操作
subimpl.doSomething();
System.out.println("after");//调用目标对象之后可以做相关操作
}
} public class Test
{
public static void main(String[] args) throws Exception
{
Subject sub = new SubjectProxy();
sub.doSomething();
}
}
可以看到,SubjectProxy实现了Subject接口(和RealSubject实现相同接口),并持有的是Subject接口类型的引用。这样调用的依然是doSomething方法,只是实例化对象的过程改变了,结果来看,代理类SubjectProxy可以自动为我们加上了before和after等我们需要的动作。
如果将来需要实现一个新的接口,就需要在代理类里再写该接口的实现方法,对导致代理类的代码变得臃肿;另一方面,当需要改变抽象角色接口时,无疑真实角色和代理角色也需要改变。
3、JDK动态代理
interface Subject
{
public void doSomething();
}
class RealSubject implements Subject
{
public void doSomething()
{
System.out.println( "call doSomething()" );
}
}
class ProxyHandler implements InvocationHandler
{
private Object tar;
//绑定委托对象,并返回代理类
public Object bind(Object tar)
{
this.tar = tar;
//绑定该类实现的所有接口,取得代理类
return Proxy.newProxyInstance(tar.getClass().getClassLoader(),
tar.getClass().getInterfaces(),
this);
}
public Object invoke(Object proxy , Method method , Object[] args)throws Throwable//不依赖具体接口实现
{
Object result = null;//被代理的类型为Object基类
//这里就可以进行所谓的AOP编程了
//在调用具体函数方法前,执行功能处理
result = method.invoke(tar,args);
//在调用具体函数方法后,执行功能处理
return result;
}
}
public class Test
{
public static void main(String args[])
{
ProxyHandler proxy = new ProxyHandler();
//绑定该类实现的所有接口
Subject sub = (Subject) proxy.bind(new RealSubject());
sub.doSomething();
}
}
在调用过程中使用了通用的代理类包装了RealSubject实例,然后调用了Jdk的代理工厂方法实例化了一个具体的代理类。最后调用代理的doSomething方法,还有附加的before、after方法可以被任意复用(只要我们在调用代码处使用这个通用代理类去包装任意想要需要包装的被代理类即可)。当接口改变的时候,虽然被代理类需要改变,但是我们的代理类却不用改变了。这个调用虽然足够灵活,可以动态生成一个具体的代理类,而不用自己显示的创建一个实现具体接口的代理类。
java动态代理、Proxy与InvocationHandler的更多相关文章
- java动态代理Proxy
package com.gz_06; public interface StudentDao { public void login(); public void regist(); } packag ...
- java 动态代理 Proxy.newProxyInstance 使用心法
使用JDk的Proxy类的静态方法newProxyInstance ,让JVM自动生成一个新的类,类中包含了inerfaces参数中的所有方法,每个方法都调用h.invoke 方法 AOP ...
- java动态代理--proxy&cglib
大纲 代理 proxy cglib 小结 一.代理 为什么要用代理?其实就是希望不修改对象的情况下,增强对象. 静态代理: 静态代理模式,需要代理类和目标类实现同一接口,代理类的方法调用目标类的方法, ...
- java 动态代理范例 InvocationHandler与Proxy
java 动态代理范例 InvocationHandler与Proxy,拦截与代理 java.lang.reflect.Proxy,Proxy 提供用于创建动态代理类和实例的静态方法.newProxy ...
- java 动态代理深度学习(Proxy,InvocationHandler),含$Proxy0源码
java 动态代理深度学习, 一.相关类及其方法: java.lang.reflect.Proxy,Proxy 提供用于创建动态代理类和实例的静态方法.newProxyInstance()返回一个指定 ...
- Java动态代理一Proxy
什么是动态代理? 动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实.代理一般会实现它所表示的实际对象的接口.代理可以访问实际对象,但是延迟实现实际对象的部分功能,实际对象实现系统的实际功 ...
- 动态代理 Proxy InvocationHandler
前奏 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等. 代理类与委托类之间通常 ...
- 浅谈Java代理一:JDK动态代理-Proxy.newProxyInstance
浅谈Java代理一:JDK动态代理-Proxy.newProxyInstance java.lang.reflect.Proxy:该类用于动态生成代理类,只需传入目标接口.目标接口的类加载器以及Inv ...
- Java动态代理(一)动态类Proxy的使用
1.什么是动态代理? 答:动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实.代理一般会实现它所表示的实际对象的接口.代理可以访问实际对象,但是延迟实现实际对象的部分功能,实际对象实现系统 ...
- 43、Java动态代理一——动态类Proxy的使用
1.什么是动态代理? 答:动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实.代理一般会实现它所表示的实际对象的接口.代理可以访问实际对象,但是延迟实现实际对象的部分功能,实际对象实现系统 ...
随机推荐
- oracle避免在索引列上使用IS NULL和IS NOT NULL
避免在索引中使用任何可以为空的列,ORACLE将无法使用该索引 .对于单列索引,如果列包含空值,索引中将不存在此记录. 对于复合索引,如果每个列都为空,索引中同样不存在此记录. 如果至少有一个列不为空 ...
- laravel 学习笔记blog后台
https://github.com/almasaeed2010/adminlte composer require "almasaeed2010/adminlte=~2.0"
- H3C 传输层
- Spring Security实现禁止用户重复登陆(配置及原理)
系统使用了Spring Security做权限管理,现在对于系统的用户,需要改动配置,实现无法多地登陆. 一.SpringMVC项目,配置如下: 首先在修改Security相关的XML,我这里是s ...
- Css布局常用 1.盒子内容局中 2. 物理一像素 3.倒三角形 绘制
布局 对象属性 new Person('') 原型链 (创建对象.使用对象中的属性,如果没有那么就去原型找) new Person() Person{ name:'', getname( ...
- P1096 4个数的全排列
题目描述 输入4个有序的个位数.按照字典序输出它们的全排列. 输入格式 输入四个数字a,b,c,d.(0<=a,b,c,d<10) 输出格式 输出它们的全排列.每个排列占一行.而且每个排列 ...
- python 使用PyInstaller遇到的坑
给个链接 https://github.com/yinghualuowu/Python_VLPR/releases 参数问题 在网上随处可以见到PyInstaller的参数教程. -F : 打包成单个 ...
- H3C DHCP服务器可选配置
- java Eclipse的使用技巧
eclipse与myeclipse的关系(都属于java开发的工具): 后者是前者的一个插件,后来为了方便使用,myeclipse集合了eclipse,后者是收费的. 可大部分人都是用 eclipse ...
- PHP PDO扩展整理,包括环境配置\基本增删改查\事务\预处理
相关文章:PHP的mysql扩展整理,操作数据库的实现过程分析 PHPmysqli扩展整理,包括面向过程和面向对象的比较\事务控制\批量执行\预处理 介绍 PDO是一种PHP程序连接数据库的接口 ...