Java基础加强——动态代理
代理模式:
为其他对象提供一种代理以控制对这个对象的访问。
代理模式主要分为两类:
静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
动态代理:在程序运行时,运用反射机制动态创建而成
1.静态代理相对好理解一些,来看下面的代码:
接口 Count.java
/**
* 账户接口
* @author jiangbei01
*
*/
public interface Count {
void add();
void update();
}
实现类 CountImpl
package cn.test;
public class CountImpl implements Count {
@Override
public void add() {
System.out.println("真实对象.add");
}
@Override
public void update() {
System.out.println("真实对象.update");
}
}
代理对象CountProxy.java
package cn.test;
public class CountProxy implements Count {
//持有真实对象引用
private CountImpl countImpl;
//覆盖默认构造器
public CountProxy(CountImpl countImpl) {
super();
this.countImpl = countImpl;
}
@Override
public void add() {
System.out.println("代理对象执行add前");
countImpl.add();
System.out.println("代理对象执行add后");
}
@Override
public void update() {
System.out.println("代理对象执行update前");
countImpl.update();
System.out.println("代理对象执行update后");
}
}
看看测试代码:
public class Test01 {
public static void main(String[] args) {
CountImpl countImpl = new CountImpl();
CountProxy countProxy = new CountProxy(countImpl);
countProxy.add();
System.out.println("===========================");
countProxy.update();
}
}
运行结果也容易得出:
代理对象执行add前
真实对象.add
代理对象执行add后
===========================
代理对象执行update前
真实对象.update
代理对象执行update后
容易看出静态代理缺点:每个代理只能为一个接口服务,并且重复代码量大!
2.动态代理:java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。
每一个动态代理类都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler,
当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用。
推荐博客:http://www.cnblogs.com/xiaoluo501395377/p/3383130.html
代理类处理的逻辑很简单:在调用某个方法前及方法后做一些额外的业务。换一种思路就是:
在触发(invoke)真实角色的方法之前或者之后做一些额外的业务。那么,为了构造出具有通用性和简单性的代理类,
可以将所有的触发真实角色动作交给一个触发的管理器,让这个管理器统一地管理触发。这种管理器就是Invocation Handler。
推荐文档:http://www.360doc.com/content/14/0801/14/1073512_398598312.shtml
我们来看看InvocationHandler这个接口的唯一一个方法 invoke 方法:
Proxy类提供的方法:
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
其中最后一个参数 InvocationHandler h 得到InvocationHandler接口的子类实例
ClassLoader loader用来指明生成代理对象使用哪个类装载器,(Proxy.class.getClassLoader())
Class<?>[] interfaces用来指明生成哪个对象的代理对象,通过接口指定,
InvocationHandler h用来指明产生的这个代理对象要做什么事情。
下面来看一个例子:
先定义一个接口:Person.java
public interface Person {
String sing(String musicName);
String speak(String text);
}
给出一个实现类:薛之谦 XueZhiQian.java
public class XueZhiQian implements Person {
@Override
public String sing(String musicName) {
System.out.println("薛之谦唱了 "+musicName);
return "歌曲唱完,谢谢各位!";
}
@Override
public String speak(String text) {
System.out.println("薛之谦说了 "+text);
return "话已讲完,谢谢各位!";
}
}
生成代理对象的代理类:XueZhiQianProxy.java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class XueZhiQianProxy { //要代理的对象
private Person xzq = new XueZhiQian(); public Person getProxy(){
return (Person)Proxy.newProxyInstance(XueZhiQianProxy.class.getClassLoader(),
xzq.getClass().getInterfaces(),
new InvocationHandler() { @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equals("sing")){
System.out.println("找薛之谦唱歌需要先交2W!");
return method.invoke(xzq, args);
}
if(method.getName().equals("speak")){
System.out.println("找薛之谦唱歌需要先交10W!");
return method.invoke(xzq, args);
}
return null;
}
});
}
}
测试代码:
public class Test01 {
public static void main(String[] args) {
XueZhiQianProxy proxy = new XueZhiQianProxy();
Person p = proxy.getProxy();
String s1 = p.sing("演员");
System.out.println(s1);
String s2 = p.speak("段子");
System.out.println(s2);
}
}
测试结果:
找薛之谦唱歌需要先交2W!
薛之谦唱了 演员
歌曲唱完,谢谢各位!
找薛之谦唱歌需要先交10W!
薛之谦说了 段子
话已讲完,谢谢各位!
Java基础加强——动态代理的更多相关文章
- Java基础-CGLIB动态代理
JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继 ...
- Java基础-JDK动态代理
JDK的动态代理依靠接口实现 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代 ...
- Java基础-jdk动态代理与cglib动态代理区别
JDK动态代理 此时代理对象和目标对象实现了相同的接口,目标对象作为代理对象的一个属性,具体接口实现中,可以在调用目标对象相应方法前后加上其他业务处理逻辑. 代理模式在实际使用时需要指定具体的目标对象 ...
- 重学JAVA基础(三):动态代理
1.接口 public interface Hello { public void sayHello(); } 2.实例类 public class Hello2 { public void sayH ...
- 黑马程序员:Java基础总结----静态代理模式&动态代理
黑马程序员:Java基础总结 静态代理模式&动态代理 ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 静态代理模式 public class Ts { ...
- 杨晓峰-Java核心技术-6 动态代理 反射 MD
目录 第6讲 | 动态代理是基于什么原理? 典型回答 考点分析 知识扩展 反射机制及其演进 动态代理 精选留言 Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAnd ...
- java反射和动态代理实现与原理详细分析
关于Java中的动态代理,我们首先需要了解的是一种常用的设计模式--代理模式,而对于代理,根据创建代理类的时间点,又可以分为静态代理和动态代理. 一.代理模式 代理模式是常用的java设计模式, ...
- 使用Java中的动态代理实现数据库连接池
2002 年 12 月 05 日 作者通过使用JAVA中的动态代理实现数据库连接池,使使用者可以以普通的jdbc连接的使用习惯来使用连接池. 数据库连接池在编写应用服务是经常需要用到的模块,太过频繁的 ...
- java 笔记(3) —— 动态代理,静态代理,cglib代理
0.代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口. 代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等. 代理类与委托类之间通常会存 ...
随机推荐
- WiFi 干扰器,有时间可以去试试呦!
转自社区: 0X01 引言 想不想搞个WIFI干扰器?网上搜集了一下资料,发现用esp8266可以实现简单的干扰功能,包括断网.复制.欺骗等等.刚好手上有块Tpyboard V202(30元),也是e ...
- PHP接收IOS post过来的json数据无法解析的问题
在本地环境下运行解析OK 换到线上的环境解析失败 开始怀疑各种编码问题,解决均无效. 查看phpinfo 发现magic_quotes_gpc =on 终于找到问题所在,更改php.ini文件 mag ...
- C# 标准的MD5加密32位
标准的MD5加密32位小写的: public static string GetMD5(string myString) { MD5 md5 = new MD5CryptoServiceProvide ...
- MySQL InnoDB锁机制之Gap Lock、Next-Key Lock、Record Lock解析
MySQL InnoDB支持三种行锁定方式: l 行锁(Record Lock):锁直接加在索引记录上面,锁住的是key. l 间隙锁(Gap Lock):锁定索引记录间隙,确保索引记录的间隙 ...
- 《C++ Primer Plus》读书笔记之七—内存模型和名称空间
第九章 内存模型和名称空间 1.不要将函数定义或者变量声明放到头文件中. 2.头文件常包含的内容:函数原型.使用#define或者const定义的常量.结构声明.类声明.模板声明.内联函数. 3.避免 ...
- CSS学习摘要-定位
CSS学习摘要-定位 注:全文摘自MDN-CSS定位 定位允许您从正常的文档流布局中取出元素,并使它们具有不同的行为,例如放在另一个元素的上面,或者始终保持在浏览器视窗内的同一位置. 本文解释的是定位 ...
- Ardunio控制RGB的LED灯显示彩虹渐变色.
由于我使用的是共阴极的RGB LED,如果你的是共阳极的,接线的时候要注意一下. 其他没什么不同 //定义RGB色彩的输出I/O ; ; ; //标记颜色变化的方式,增加值还是减小值 bool red ...
- UI(二)之正式过程
2018-12-04 09:48:25 1.SetWindowsHookEx ·钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统.每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获 ...
- 事后诸葛亮之Alpha十天冲刺之失败总结
参考自构建之法p341页的模板 首先自己预计了一下,项目gg的可能有百分之50这里面有百分之80是我的责任.冲刺失败我承担主要责任. 1.设想和目标: 1.计划实现类似华为云的小功能之团队合作开发功能 ...
- php 实现hash表
hash表又称散列表,通过把关键字key经过hash函数映射到hash表中某个位置获取记录. 存放记录的数组又称为hash表,映射函数称为hash函数 下面是php中实现hash表的方法 <?p ...