黑马程序员:Java编程_动态代理
=========== ASP.Net+Android+IOS开发、.Net培训、期待与您交流!===========
长沙人从长沙的代理商手中买宏基电脑和直接跑到宏基总部买电脑,最终的主体业务目标有什么区别吗?基本一样,都解决了核心问题,但是,一点区别都没有吗?从代理商那里买真的一点好处都没有吗?
要为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能,例如,异常处理、日志、计算方法的运行时间、事务管理、等等,你准备如何做?在现实生活中,我们可以从代理商手中拿货;程序中我们可以编写一个与目标类具有相同接口的代理类(类似宏基代理商有宏基电脑),代理类的每个方法调用目标类的相同方法,并在调用方法时加上系统功能的代码(类似代理商要赚取差价)。要为系统中的各种接口的类增加代理功能,那将需要太多的代理类,全部采用静态代理方式,将是一件非常麻烦的事情!JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类。
动态代理类的字节码在程序运行时由Java反射机制动态生成,动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中提供的和动态代理有关的Proxy类和InvocationHandler 接口有生成动态代理类的能力:
public interface InvocationHandler{
Object invoke(Object proxy, Method method, Object[] args)throws Throwable ;
}
class Proxy 真正表示动态代理的类,提供两个静态方法:
Class<?> getProxyClass(ClassLoader loader, Class<?>[] interface) 用来产生代理类,参数要提供interface数组,它会生成这些interface的“虚拟实现”, 用来冒充真实的对象。
Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 产生代理对象,多了InvocationHandler参数(只是InvocationHandler接口的实现类), 它与代理对象关联,当请求分发到代理对象后,会自动执行h.invoke(...)方法, invoke方法就是我们加上系统功能的代码的地方。
A接口有c方法,类B实现A接口,原本应该是执行B类中的c方法,可现在不这样做; 我声明产生B类的代理类B',由它来冒充B类的“兄弟”并“实现”A接口, 对外界来说B'应该也有c方法,可当真正调用它的时候, 它会去执行与它关联InvocationHandler的invoke()方法, 在这个方法里面你可以做很多事情。这样,这个请求就被“代理”到其它地方去了。这就是JDK的动态代理,必须依靠接口实现。如果有些类并没有实现接口,则不能使用JDK代理,这就要使用cglib动态代理了,cglib动态代理以后研究再加上。
动态代理示例:
1. A接口
public interface AInterface {
public void add();
}
2. 类B实现接口,即目标:
public class BImpl implements AInterface {
@Override
public void add() {
System.out.println("增加方法。。。");
}
}
3. B类的代理类B':
import java.lang.reflect.*;
public class BProxy implements InvocationHandler {
private Object target;
private Advice advice;
/**
* 构造方法绑定委托对象及“建议”
*/
BProxy(Object target,Advice advice)
{
this.target = target;
this.advice = advice;
}
public Object getProxy() {
//取得代理对象
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this); 一//要绑定接口(这是一个缺陷,cglib弥补了这缺陷)
}
@Override
/**
* 调用方法
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result=null;
//将要对目标进行“加工”的内容进行封装
advice.before();
//执行目标
result=method.invoke(target, args);
advice.after();
return result;
}
}
4. 代理对目标的加工接口及其实例:
interface Advice
{
void before();
void after();
} class MyAdvice implements Advice
{
public void before(){
System.out.println("前面运行");
}
public void after(){
System.out.println("后面运行");
}
}
5. 代理测试:
public class TestProxy {
public static void main(String[] args) {
AInterface BProxy = (AInterface)new BProxy(new BImpl(),new MyAdvice()).getProxy();
BProxy.add();
}
}
-----------☆-----------ASP.Net+Android+IOS开发、.Net培训、期待与您交流! -----------☆-----------
详细请查看: http://edu.csdn.net
黑马程序员:Java编程_动态代理的更多相关文章
- 【黑马18期Java毕业生】黑马程序员Java全套资料+视频+工具
Java学习路线图引言: 黑马程序员:深知广大爱好Java的人学习是多么困难,没视频没资源,上网花钱还老被骗. 为此我们历时一个月整理这套Java学习路线图,不管你是不懂电脑的小 ...
- [刘阳Java]_程序员Java编程进阶的5个注意点,别编程两三年还是增删改查
此文章也是关注网上好几篇技术文章后,今天分享出来.因为,总有在程序学习路上的小伙伴会感到迷茫.而迷茫存在的情况如下 第一种:在大学学习中出现的迷茫,不知道Java到底要学什么.学习Java的标准是什么 ...
- 黑马程序员Java基础班+就业班课程笔记全发布(持续更新)
正在黑马学习,整理了一些课程知识点和比较重要的内容分享给大家,也是给自己拓宽一些视野,仅供大家交流学习,大家有什么更好的内容可以发给我 ,现有黑马教程2000G QQ 1481135711 这是我总 ...
- 黑马程序员——JAVA基础之语法、命名规则
------- android培训.java培训.期待与您交流! ---------- 1.java语言组成:关键字,标识符,注释,常量和变量,运算符,语句,函数,数组. 2.java关键字:被Jav ...
- 黑马程序员----java基础笔记中(毕向东)
<p>------<a href="http://www.itheima.com" target="blank">Java培训.Andr ...
- 黑马程序员——JAVA基础之泛型和通配符
------- android培训.java培训.期待与您交流! ---------- 泛型: JDK1.5版本以后出现新特性.用于解决安全问题,是一个类型安全机制. 泛型好处: ...
- 黑马程序员——JAVA基础之简述面向对象,类,变量,匿名对象
------- android培训.java培训.期待与您交流! ---------- 面向对象: 面向对象是相对面向过程而言 面向对象和面向过程都是一种思想 面向过程 强调的是功能行为 面向对象 将 ...
- 黑马程序员----java基础:异常
dff ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 经常写程序的人对try...catch...finally语句肯定是不陌生的了.但是好多 ...
- 黑马程序员——JAVA基础之网络编程
------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 网络编程 网络模型:OSI参考模型和TCP/IP参考模型 网络通讯三要素: IP地址:InetA ...
随机推荐
- Android中的动态加载机制
在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优势.本 ...
- 【iOS】The differences between Class Extension and Header File 类扩展与头文件的区别
. As the name suggests, they extend the class. A class continuation is another name. The class exten ...
- mysql 通过IP连接
解决方法如下: 编辑my.ini 在[mysqld]节点下新增或修改如下两行行 skip-name-resolve #忽略主机名的方式访问 lower_case_table_names= #忽略数据库 ...
- Java-String类的常用方法总结
一.String类String类在java.lang包中,java使用String类创建一个字符串变量,字符串变量属于对象.java把String类声明的final类,不能有类.String类对象创建 ...
- Working with Binary Data in Python
http://www.devdungeon.com/content/working-binary-data-python
- C#的多态性
参考网址:http://www.cnblogs.com/zhangkai2237/archive/2012/12/20/2826734.html 多态的定义:同一操作作用于不同的对象,可以有不同的解释 ...
- Android Studio教程从入门到精通
最新2.0系列文章参考: Android Studio2.0 教程从入门到精通Windows版 - 安装篇Android Studio2.0 教程从入门到精通Windows版 - 入门篇Android ...
- VRP
VRP系统命令采用分级保护方式,命令被划分为参观级.监控级.配置级.管理级4个级别. 参观级:网络诊断工具命令(ping.tracert).从本设备出发访问外部设备的命令(包括:Telnet客户端.S ...
- Java多线程干货系列(1):Java多线程基础
原文出处: 嘟嘟MD 前言 多线程并发编程是Java编程中重要的一块内容,也是面试重点覆盖区域,所以学好多线程并发编程对我们来说极其重要,下面跟我一起开启本次的学习之旅吧. 正文 线程与进程 1 线程 ...
- Android基础:Activity
Activity基本概念 Activity代表活动窗口,通过Context加载页面显示内容,每一个Activity都必须在manifest.xml中注册. 一个应用程序由多个界面构成,回退栈,活动窗口 ...