Java-动态代理技术
1.程序中的代理
为具有相同接口的目标类的各个方法,添加一些系统功能,如日志,异常处理,计算方法运行的
时间,事务管理等等,都可以交给另一个类去实现这些功能,该类称为代理类。
注意:为了让代理类共享目标类中的各个方法,可以让代理类实现和目标类相同的接口。

public class AProxy {
//AProxy类为A的代理类,可以计算sayHi方法的运行时间
public void getTime()
{
//方法开始前时间
new A().sayHi();
//方法结束后时间
}
}
class A
{
void sayHi()
{
System.out.println("hi,everyone!");
}
}

2.代理架构图
它采用工厂模式和配置文件的方式进行管理,这样就不需要修改客户端程序,通过
配置文件指定使用目标类,还是代理类。这样做添加/去掉系统功能变得简单。
当我们需要测试系统的性能时,可以使用代理类,客户要使用时可以使用目标类
3.AOP(Aspect oriented program)
交叉业务:要处理不同层面的业务(service),称为交叉业务,如安全,事务,日志等。
安全 事务 日志
StudentService ------|----------|------------|-------------
CourseService ------|----------|------------|-------------
MiscService ------|----------|------------|-------------
用具体的程序代码描述交叉业务:
method1 method2 method3
{ { {
------------------------------------------------------切面
.... .... ......
------------------------------------------------------切面
} } }
面向方面的编程(简称AOP),AOP的目标就是要使交叉业务模块化。
可以采用将切面代码移动到原始方法的周围,这与直接在方法中编写切面代码的运行效果是一样的,如下所示:
------------------------------------------------------切面
func1 func2 func3
{ { {
.... .... ......
} } }
------------------------------------------------------切面
这里就是使用代理技术解决这种问题,代理是实现AOP功能的核心和关键技术。
4.动态代理技术
- 要为系统中的各种接口的类增加代理功能,那将需要太多的代理类,全部采用静态代理方式,将是一件非常麻烦的事情!
- JVM提供了动态代理类(Proxy)。即可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类。这里是仅指具有接口的代理类和目标类。
- 对于没有接口的目标类,CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB库。
代理方法中的有如下四个位置加上系统功能代码:
1.在调用目标方法之前
2.在调用目标方法之后
3.在调用目标方法前后
4.在处理目标方法异常的catch块中

class proxy{
void sayHello(){
………//1
try{
target.sayHello();
}catch(Exception e){
………//4
}
…………//2
}
}

5.Proxy(代理类)
|-java.lang.reflect.Proxy
Proxy提供了创建动态代理类和实例的静态方法,它也是这些创建出来类的超(父)类。
构造方法:
protected Proxy(InvocationHandler h);//使用其调用处理程序的指定值从子类(通常为动态代理类)构建新的 Proxy
实例
成员方法:
static Class<?> getProxyClass(ClassLoader loader,Class<?> interfaces);//创建一个具有接口的动态代理类。
static Object newProxyInstance (ClassLoader loader,Class<?>[] interfaces,InvocationHandler h);//返回一个代理类实例对象
创建代理类及其实例对象:
法一:先创建代理类,再用代理类的构造方法创建实例对象

public static void main(String[] args) {
// 获得一个集合接口的代理类,为其指定接口和类加载器
//通常loader,interface是一样的字节码产生的
Class clazzProxy1=Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
System.out.println(clazzProxy1.getName());
//创建一个代理类实例
//注意:clazzProxy1.newInstance()调用的是它的无参构造方法创建实例,但是它没有无参的构造方法
//通过有参构造方法创建实例
Constructor ct=clazzProxy1.getConstructor(InvocationHandler.class);
class MyinvocationHandler implements InvocationHandler
{
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
}
Collection proxy1=(Collection) ct.newInstance(new MyinvocationHandler());
}}

法二:用new方法直接创建代理类实例对象

Object target=new Object ();
Object proxy1=Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(), new InvocationHandler(){ @Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
return null;
}
}); Class<?> []cs={Collection.class};
Collection proxy3=(Collection)Proxy.newProxyInstance
(Collection.class.getClassLoader(),
cs,new MyinvocationHandler());
Collection proxy4=(Collection)Proxy.newProxyInstance
(Collection.class.getClassLoader(),
new Class[] {Collection.class},
new MyinvocationHandler());

6.InvocationHandler(接口)
成员方法:
Object invoke(Object proxy, Method method, Object[] args);//
在代理实例上处理方法调用并返回结果。
事实上,Proxy代理类对象调用(该接口上的)方法时,其实是去调用了handler的
invoke方法。对于不是该接口上的方法,如getClass(),则调用它本身的,不用委托handler去调用invoke方法。
7.代理类的模式
以面向对象的思想处理AOP(面向方面编程)的业务,即在实现代理的系统功能时,将目标类对象和接口(该接口通常以实现接口某个类的方式传入,实现接口里的方法(系统功能)的类)作为参数传入一个要实现系统功能的方法中。

ArrayList al=new ArrayList();
Collection proxy4=(Collection)getProxy(al,new Myadvice());
proxy4.add("hq");
//以下是封装了实现代理功能的一个方法
//参数:目标类对象,和接口(实现代理功能的类,类里有实现功能的方法),该接口通常以实现接口某个类的方式传入。
private static Object getProxy(final Object target,final interfaceAdvice advice) {
Object proxy=Proxy.newProxyInstance
(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler(){ @Override
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
advice.beforeMethod(method);
Object obj=method.invoke(target, args);
advice.afterMethod(method);
return obj;
}
});
return proxy;
}

8.实现AOP功能的封装与配置
工厂类BeanFactory负责创建目标类或代理类的实例对象,并通过配置文件实现切换。其getBean方法根据参数字符串返回一个相应的实例 对象,如果参数字符串在配置文件中对应的类名不是ProxyFactoryBean,则直接返回该类的实例对象,否则,返回该类实例对象的 getProxy方法返回的对象。
BeanFactory的构造方法接收代表配置文件的输入流对象,配置文件格式如下:
#xxx=java.util.ArrayList
xxx=cn.itcast.ProxyFactoryBean
xxx.target=java.util.ArrayList
xxx.advice=cn.itcast.MyAdvice
ProxyFacotryBean充当封装生成动态代理的工厂,需要为工厂类提供哪些配置参数信息?
目标:target
通知:advice
编写客户端应用:
编写实现Advice接口的类和在配置文件中进行配置
调用BeanFactory获取对象。
摘自:
http://www.cnblogs.com/beyondbycyx/p/4314536.html
Java-动态代理技术的更多相关文章
- java动态代理技术
主要用来做方法的增强.让你能够在不改动源代码的情况下,增强一些方法,在方法运行前后做不论什么你想做的事情(甚至根本不去运行这种方法).由于在InvocationHandler的invoke方法中,你能 ...
- 代理模式 & Java原生动态代理技术 & CGLib动态代理技术
第一部分.代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常 ...
- Java中动态代理技术生成的类与原始类的区别 (转)
用动态代理的时候,对它新生成的类长什么样子感到好奇.有幸通过一些资料消除了心里的疑惑. 平时工作使用的Spring框架里面有一个AOP(面向切面)的机制,只知道它是把类重新生成了一遍,在切面上加上了后 ...
- Java中动态代理技术生成的类与原始类的区别
用动态代理的时候,对它新生成的类长什么样子感到好奇.有幸通过一些资料消除了心里的疑惑. 平时工作使用的Spring框架里面有一个AOP(面向切面)的机制,只知道它是把类重新生成了一遍,在切面上加上了后 ...
- Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架
类加载器 Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader 类加载器也是Jav ...
- Java中动态代理技术生成的类与原始类的区别 (good)
用动态代理的时候,对它新生成的类长什么样子感到好奇.有幸通过一些资料消除了心里的疑惑. 平时工作使用的Spring框架里面有一个AOP(面向切面)的机制,只知道它是把类重新生成了一遍,在切面上加上了后 ...
- java动态代理原理
我们经常会用到Java的动态代理技术, 虽然会使用, 但是自己对其中的原理却不是很了解.比如代理对象是如何产生的, InvocationHandler的invoke方法是如何调用的?今天就来深究下Ja ...
- 【转载】Java 动态代理
Java 动态代理 本文为 Android 开源项目源码解析 公共技术点中的 动态代理 部分项目地址:Jave Proxy,分析的版本:openjdk 1.6,Demo 地址:Proxy Demo分析 ...
- Java动态代理简单应用
概念 代理模式是基本的设计模式之一,它是开发者为了提供额外的或不同的操作,而插入的用来代替“实际”对象的对象.这些操作通常涉及与“实际”对象的通信,因此代理通常充当着中间人的角色. Java动态代理比 ...
- Spring AOP 和 动态代理技术
AOP 是什么东西 首先来说 AOP 并不是 Spring 框架的核心技术之一,AOP 全称 Aspect Orient Programming,即面向切面的编程.其要解决的问题就是在不改变源代码的情 ...
随机推荐
- 6.26实力测试(小错笑cry)
6.26测试 本次考试的粗心不忍吐槽(自带贴吧喷水表情),本次考试主要考察的知识点如下: 算法的分析与精简 暴力枚举输出字符 判断与枚举的综合考察 题目 第一题 [问题描述] 在一口井里,有一只神牛( ...
- centos7中输入ifconfig出现ens33,没有eth0(转)
vmware安装的centos7中没有出现eth0网卡,也没有ip,不能上网,输入ifconfig后如下图 解决办法 1.编辑网卡的配置文件 vi /etc/sysconfig/network-scr ...
- Netty Reator(三)Reactor 模型
Netty Reator(三)Reactor 模型 Netty 系列目录 (https://www.cnblogs.com/binarylei/p/10117436.html) 本文介绍 DC Sch ...
- msgs no .h file
1.单独编译包,catkin_make --pkg 包名,failed,则 2.进入build下对应的msgs包中,使用make,以及make install,failed,则 3.使用catkin_ ...
- IOS初级:story board的跳转
本文要实现view1跳到view2,view2又跳回view1. 首先要在视图中拉出一条连接view1和view2的线. 下面是在view1的控制器中实现,从view1跳到view2 //发生跳转前会 ...
- OneZero第三周——预完成功能点统计
本周OneZero将完成“摇一摇”功能. 功能点统计如下: 1.点击主页面“摇一摇”按钮,进入摇一摇界面. 2.摇一摇界面布局(上,中,下). 3.摇动手机,在摇一摇界面中显示一条消费记录. 4.继续 ...
- css兼容技巧
CSS兼容常用技巧 请尽量用xhtml格式写代码,而且DOCTYPE影响 CSS 处理,作为W3C标准,一定要加DOCTYPE声明. 1.div的垂直居中问题 vertical-align:middl ...
- 2019.01.21 bzoj1758: [Wc2010]重建计划(01分数规划+长链剖分+线段树)
传送门 长链剖分好题. 题意简述:给一棵树,问边数在[L,R][L,R][L,R]之间的路径权值和与边数之比的最大值. 思路: 用脚指头想都知道要01分数规划. 考虑怎么checkcheckcheck ...
- 2018.12.08 codeforces 946D. Timetable(背包)
传送门 题意简述:有一个人上n天课,每天有m个小时的时间安排表(一个01串),为1表示要上课,否则不上课,求出如果可以最多翘kkk节课这nnn天在校待的总时间的最小值(一天必须在所有课上完后才能离开) ...
- 2018.11.17 bzoj4259: 残缺的字符串(fft)
传送门 fftfftfft套路题. 我们把aaa ~ zzz映射成111 ~ 262626,然后把∗*∗映射成000. 考虑对于两个长度都为nnn的字符串A,BA,BA,B. 我们定义一个差异函数di ...