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,即面向切面的编程.其要解决的问题就是在不改变源代码的情 ...
随机推荐
- Autel MaxiSys MS906TS tire pressure settings Lexus LS460h
Use AUTEL MaxiSYS MS906TS error reader to install tire pressure Lexus LS460h in Vung Tau. Make : Lex ...
- px转rem
第一步: 第二步:html引入js 第三步:转换单位,100px=0.1rem
- 数组转xml格式/xml格式转数组
数组转xml格式 $arr=array( 'username'=>'huahua', 'password'=>'123456', 'number'=>'15889652911', ) ...
- windows driver
C:\Windows\System32\DriverStore\FileRepository
- Linux产生序列数字
{起始数字..结束数字} // 注意 起始数字和结束数字都包括在内 中间没有空格
- HashMap 、HashTable、TreeMap、WeakHashMap的区别是什么
Java为数据结构中的映射定义了一个接口java.util.Map,它有4个实现类:HashTable.HashMap.TreeMap.WeakHashMap. HashMap和HashTable的区 ...
- POI导出大量数据的简单解决方案
说明:我的电脑 2.0CPU 2G内存 能够十秒钟导出 20W 条数据 ,12.8M的excel内容压缩后2.68M 我们知道在POI导出Excel时,数据量大了,很容易导致内存溢出.由于Excel ...
- ssh定义、操作
Secure Shell(縮寫为SSH)SSH為一项建立在应用层和传输层基础上的安全协议,为计算机上的Shell(壳层)提供安全的传输和使用环境. 传统的网络服务程序,如rsh.FTP.POP和Tel ...
- 2019.01.09 bzoj3697: 采药人的路径(点分治)
传送门 点分治好题. 题意:给出一棵树,边分两种,求满足由两条两种边数相等的路径拼成的路径数. 思路: 考虑将边的种类转化成边权−1-1−1和111,这样就只用考虑由两条权值为000的路径拼成的路径数 ...
- 关于SQL表字段值缺失的处理办法
在计算收益率时候, 收益率 = 收益 / 成本 一.如果成本为0,NULL,此时无法计算收益率: 方法: 1.将成本为0的数据 运算 (case when cost =0 or cost is n ...