黑马程序员——动态代理技术
来源:互联网 发布:写作软件哪个好 编辑:程序博客网 时间:2024/06/05 07:15
------- android培训、java培训、期待与您交流! ----------
相关概念
生活中的代理
生活中的代理随处可见:相比比从商品的源公司直接购买商品和获得服务,人们从代理商那购买商品和获得服务更加方便和节约时间、金钱成本。
程序中的代理
需求:为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能,如:异常处理、日志、计算方法的运算时间、事物管理等。思路:
1)编写一个与目标类具有相同接口的代理类;
2)代理类的每个方法调用目标类的相同方法;
3)并在调用方法时加上系统功能的代码。
:图1:代理构架图(重要),需理解图的含义,并且会自己画。
面向切面编程AOP
需求:安全、事务、日志等功能要贯穿到好多个模块中,所以它们就是交叉业务。
原理:我们不可能去修改方法,深入到方法内部去修改,但是我们能让用户感觉到就是在方法前或后加了代码,就把切面代码转移到方法执行前和执行后。
重要原则:“不要把供应商暴漏给你的客户”。
动态代理技术及CGLIB
分析:要为系统中的各种接口的类增加代理功能,那将需要太多的代理类,且全部采用静态代理方式将需要写成百上千的代理类;JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类;
动态代理及CGLIB库:JVM生成动态类必须实现一个或多个接口,所以JVM生成的动态类智能用作具有相同接口的目标类的代理;而CGLIB库可以动态生成一个类的子类,一个类的子类也可以用用该类的代理,所以如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB库;代理类的各个方法中通常除了要调用目标的相应方法和对外返回目标返回的结果外,还可以在代理方法中的四个位置加上系统功能代码:
1)在调用目标方法之前;
2)在调用目标方法之后;
3)在调用目标方法前后;
4)在处理目标方法异常的catch块中。
知识点与代码
Proxy类
Proxy类位于java.lang.reflect.Proxy包,它提供了一个核心方法 static Class<?> getProxyClass(ClassLoaderloader, Class<?>... interfaces):返回代理类的java.lang.Class对象,并向其提供类加载器和接口数组。
创建动态代理,代码
在代码通过演练分析来解决创动态建代理类的一个个问题,为分析、创建完善的动代理类做准备;其中通过三种方式的演变:
总结思考方式一到方式二
让JVM创建动态类及其实例对象,需要给它提供三个方面的信息:
1)生成的类中有哪些方法,通过让其实现哪些接口的方式进行告知;
2)产生的类字节码必须有一个关联的类加载器对象;
3)生成类的方法的代码是怎样实现的,也得由我们提供。把我们的代码写在一个约定好了接口对象的方法中,把对象传给它,它调用我的方法,即相当于插入了我的代码;提供执行代码的对象就是那个InvocationHandler对象,它是在创见动态类的实例对象的构造方法时传递进去的。在上面的InvocationHandler对象的invoke方法中加一点代码,就可以看到这些代码被调用运行了。
4)而用Proxy.newProxyInstance方法直接一步就创建出代理对象。
总结思考方式二到方式三
java.lang.reflect.Proxy包下的类Proxy,方法newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
:返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。此方法相当于:
Proxy.getProxyClass(loader, interfaces). getConstructor(new Class[] { InvocationHandler.class }). newInstance(new Object[] { handler });
loader
- 定义代理类的类加载器interfaces
- 代理类要实现的接口列表h
- 指派方法调用的调用处理程序抛出:
IllegalArgumentException
- 如果违反传递到getProxyClass
的参数上的任何限制NullPointerException
- 如果interfaces
数组参数或其任何元素为null
,或如果调用处理程序h
为null
分析InvocationHandler对象的运行原理
1)动态生成的类实现了Collection接口(可以实现多个接口),生成的类有Collection接口中的所有方法和一个如下接收InvocationHandler参数的构造方法;
2)构造方法接收一个InvocationHandler对象,接收对象了要干什么用呢?该方法内部代码是怎样实现的呢?
3)实现Collection接口的动态类中的各个方法的代码又是怎样的呢?
InvocationHandler接口中定义的invoke方法接收的三个参数分析如下:
Client程序调用objProxy.add(“abc”)方法时,涉及三要素:objProxy对象、add方法、“abc”参数;
Class Proxy${
add(Objectobject){
returnhandler.invoke(Object proxy, Method method, Object[] args);
}
}
其他
1、当代码中打印一个对象为null时,可以有两种情况:分析动态代理的设计原理与结构
分析过程
1、在图中的log()小圈注释的地方,不写成硬性的代码,把(系统功能)代码作为一个参数传递进去,做成框架;那么可不可以将代码写成字符串传递进来?在Java script有这样的功能;Java script是一种动态语言,可以将代码在程序运行时,植入进去一段代码让程序执行——Java现在还没有这个功能(以后Java版本可能有这样功能?);
图3:动态代理的工作原理图。
可生成代理和插入通告的通用方法,代码
总结
小框架
invoke 方法
(Object proxy,Method method, Object[] args)
throws Throwable: 在代理实例上处理方法调用并返回结果。 proxy
- 在其上调用方法的代理实例 method
- 对应于在代理实例上调用的接口方法的 Method
实例。Method
对象的声明类将是在其中声明方法的接口,该接口可以是代理类赖以继承方法的代理接口的超接口。 args
- 包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null
。基本类型的参数被包装在适当基本包装器类(如java.lang.Integer
或 java.lang.Boolean
)的实例中。返回:
从代理实例的方法调用返回的值。如果接口方法的声明返回类型是基本类型,则此方法返回的值一定是相应基本包装对象类的实例;否则,它一定是可分配到声明返回类型的类型。如果此方法返回的值为null
并且接口方法的返回类型是基本类型,则代理实例上的方法调用将抛出NullPointerException
。否则,如果此方法返回的值与上述接口方法的声明返回类型不兼容,则代理实例上的方法调用将抛出
实现类似Spring的可配置的AOP框架分析
实现AOP功能的封装与配置
步骤分四步:
1)工厂类BeanFactory负责创建目标类或代理类的实例对象,并通过配置文件实现切换。其getBean方法根据参数字符串返回一个相应的实例对象;如果参数字符串在配置文件中对应的类名不是ProxyFactoryBean,则直接返回该类的实例对象;否则,返回该类实例对象的getProxy方法返回的对象;
2)BeanFactory的构造方法接收代表配置文件的输入流对象,配置文件格式如下:
#xxx=java.util.ArrayList——符号“#”这里代表注释
xxx=cn.itcast.ProxyFactoryBean
xxx.target=java.tuil.ArrayList
xxx.advice=cn.itcast.MyAdvice
3)ProxyFactoryBean充当封装生成动态代理的工厂,需要为工厂类提供两个配置参数信息:目标、通知;
4)编写客户端应用:
a、编写实现Advice接口的类和在配置文件中进行配置;
b、调用BeanFactory获取对象。
代码
总结
Spring的两大核心技术:BeanFactory和AOP框架都在上面的代码中体现了;根据需求选择想要代理和不想要代理,都是在配置文件里配。
- 黑马程序员——动态代理技术
- 黑马程序员——动态代理技术
- 黑马程序员—动态代理
- 黑马程序员—代理与动态代理
- 黑马程序员_动态代理技术
- 黑马程序员——java代理技术
- 黑马程序员——Java动态代理
- 黑马程序员——动态代理类
- 黑马程序员——动态代理
- 黑马程序员——动态代理
- 黑马程序员——动态代理
- 黑马程序员——动态代理详解
- 黑马程序员—动态代理模式
- 黑马程序员—高新技术:动态代理
- 【黑马程序员】Java基础基础学习技术博客——动态代理
- 黑马程序员——高新技术(代理、动态代理)
- 黑马程序员——静态代理与动态代理
- 【黑马程序员】java中的--------------代理类与动态代理技术
- 前端学习——JSON格式详解
- JSP 简介
- jabberNet 发送出席信息
- C++中如何在main()函数之前执行操作?
- [原理][源代码解析]spring中@Transactional,Propagation.SUPPORTS,以及 Hibernate Session,以及jdbc Connection关系
- 黑马程序员——动态代理技术
- 基于sqlCE 3.0的数据库开发
- android状态机机制StateMachine
- 省市区 数组套字典 字典套数组
- 放逐心灵之旅
- bzoj1230[Usaco2008 Nov]lites 开关灯
- 两圆交点
- 集成百度地图API实现定位
- 字符设备开发的基本步骤