动态代理(1)----JDK动态代理 .
2013-06-24 17:32
211 查看
在Java的Java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口可以生成JDK动态代理类或动态代理对象.
Proxy提供用于创建动态代理类和代理对象的静态方法,它也是所有动态代理类的父类.如果我们在程序中为一个或多个接口动态地生成实现类,就可以使用Proxy来创建动态代理类:如果需要为一个或多个接口动态的创建实例,也可以使用Proxy类创建动态代理实例.
Proxy提供了如下两个方法来创建动态代理类和动态代理实例:
1.
staticClass<?>getProxyClass(ClassLoader loader,Class <?>...interfaces):创建一个动态代理类所对应的Class对象,该代理类将实现interfaces所指定的多个接口.第一个ClassLoader指定生成动态代理类的类加载器.
2.
staticObject newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler):直接创建一个动态代理对象,该代理对象的实现类实现了interfaces指定的系列接口,执行代理对象的每个方法时都会被替代执行InvocationHandler对象的invoke方法.
实际上,即使采用第一种方法获取了一个动态代理类之后,当程序需要通过该代理类来创建对象时一样需要传入一个InvocationHandler对象.也就是说,系统生成的每一个代理对象都有一个与之关联的InvocationHandler对象.
程序中生成动态代理对象可以采用先生成一个动态代理类,然后通过动态代理类来创建对象的方式来生成一个动态代理对象.如下代码片段
[java]
view plaincopyprint?
//创建一个InvocationHandler对象
InvocationHandler handler=new MyInvocationHandler(...);
//使用Proxy生成一个动态代理类proxyClass
Class proxyClass=Proxy.getProxyClass(Foo.class.getClassLoader(),new Class[]{Foo.class});
//获取proxyClass类中带一个InvocationHandler参数的构造器
Constructor<T> ctor =proxyClass.getConstructor(new Class[]{InvocationHandler.class});
//调用ctor的newInstance方法来创建动态实例
Foo f=(Foo)ctor.newInstance(new Object[]{handler});
上面代码可以简化成如下代码
[java]
view plaincopyprint?
//创建一个InvocationHandler对象
InvocationHandler hanlder=new MyInvocationHandler(...);
//使用Proxy直接生成一个动态代理对象
Foo f=(Foo)Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[]{Foo.class},handler);
下面程序示范了使用Proxy和InvocationHandler来生成动态代理对象
[java]
view plaincopyprint?
public class ProxyTest {
public static void main(String[] args) throws Exception{
//创建一个InvocationHandler对象
InvocationHandler handler=new MyInvokationHandler();
//使用指定的InvocationHanlder来生成一个动态代理对象
PersonPro p=(PersonPro)Proxy.newProxyInstance(PersonPro.class.getClassLoader(), new Class[]{PersonPro.class}, handler);
//调用动态代理对象的walk()方法和sayHello()方法
p.walk();
p.sayHello("luck");
}
}
interface PersonPro{
void walk();
void sayHello(String name);
}
class MyInvokationHandler implements InvocationHandler{
/*
* 执行动态代理对象的所有方法时,都会被替换成执行如下invoke方法
* 其中:
* proxy--代表动态代理对象
* method--代表正在执行的方法
* args--代表执行代理对象方法时传入的实参
*/
public Object invoke(Object proxy,Method method,Object[] args){
System.out.println("正在执行的方法:"+method);
if(args!=null){
System.out.println("下面是执行该方法时传入的实参:");
for(Object val:args){
System.out.println(val);
}
}else{
System.out.println("调用该方法无须实参");
}
return null;
}
}
上面程序中提供了一个Person接口,该接口中包含了walk和sayHello两个抽象方法,接着程序定义了一个简单的InvocationHandler实现类,定义该实现类时需要重写invoke方法----执行代理对象所有方法执行时将会替换成执行此invoke方法.
从运行结果中可以看出,不管程序执行代理对象的walk()方法,还是执行代理对象的sayHello()方法,实际上都是执行InvocationHandler对象的invoke()方法.
下一篇文章将实现Spring中AOP的动态代理的demo
Proxy提供用于创建动态代理类和代理对象的静态方法,它也是所有动态代理类的父类.如果我们在程序中为一个或多个接口动态地生成实现类,就可以使用Proxy来创建动态代理类:如果需要为一个或多个接口动态的创建实例,也可以使用Proxy类创建动态代理实例.
Proxy提供了如下两个方法来创建动态代理类和动态代理实例:
1.
staticClass<?>getProxyClass(ClassLoader loader,Class <?>...interfaces):创建一个动态代理类所对应的Class对象,该代理类将实现interfaces所指定的多个接口.第一个ClassLoader指定生成动态代理类的类加载器.
2.
staticObject newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler):直接创建一个动态代理对象,该代理对象的实现类实现了interfaces指定的系列接口,执行代理对象的每个方法时都会被替代执行InvocationHandler对象的invoke方法.
实际上,即使采用第一种方法获取了一个动态代理类之后,当程序需要通过该代理类来创建对象时一样需要传入一个InvocationHandler对象.也就是说,系统生成的每一个代理对象都有一个与之关联的InvocationHandler对象.
程序中生成动态代理对象可以采用先生成一个动态代理类,然后通过动态代理类来创建对象的方式来生成一个动态代理对象.如下代码片段
[java]
view plaincopyprint?
//创建一个InvocationHandler对象
InvocationHandler handler=new MyInvocationHandler(...);
//使用Proxy生成一个动态代理类proxyClass
Class proxyClass=Proxy.getProxyClass(Foo.class.getClassLoader(),new Class[]{Foo.class});
//获取proxyClass类中带一个InvocationHandler参数的构造器
Constructor<T> ctor =proxyClass.getConstructor(new Class[]{InvocationHandler.class});
//调用ctor的newInstance方法来创建动态实例
Foo f=(Foo)ctor.newInstance(new Object[]{handler});
//创建一个InvocationHandler对象 InvocationHandler handler=new MyInvocationHandler(...); //使用Proxy生成一个动态代理类proxyClass Class proxyClass=Proxy.getProxyClass(Foo.class.getClassLoader(),new Class[]{Foo.class}); //获取proxyClass类中带一个InvocationHandler参数的构造器 Constructor<T> ctor =proxyClass.getConstructor(new Class[]{InvocationHandler.class}); //调用ctor的newInstance方法来创建动态实例 Foo f=(Foo)ctor.newInstance(new Object[]{handler});
上面代码可以简化成如下代码
[java]
view plaincopyprint?
//创建一个InvocationHandler对象
InvocationHandler hanlder=new MyInvocationHandler(...);
//使用Proxy直接生成一个动态代理对象
Foo f=(Foo)Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[]{Foo.class},handler);
//创建一个InvocationHandler对象 InvocationHandler hanlder=new MyInvocationHandler(...); //使用Proxy直接生成一个动态代理对象 Foo f=(Foo)Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[]{Foo.class},handler);
下面程序示范了使用Proxy和InvocationHandler来生成动态代理对象
[java]
view plaincopyprint?
public class ProxyTest {
public static void main(String[] args) throws Exception{
//创建一个InvocationHandler对象
InvocationHandler handler=new MyInvokationHandler();
//使用指定的InvocationHanlder来生成一个动态代理对象
PersonPro p=(PersonPro)Proxy.newProxyInstance(PersonPro.class.getClassLoader(), new Class[]{PersonPro.class}, handler);
//调用动态代理对象的walk()方法和sayHello()方法
p.walk();
p.sayHello("luck");
}
}
interface PersonPro{
void walk();
void sayHello(String name);
}
class MyInvokationHandler implements InvocationHandler{
/*
* 执行动态代理对象的所有方法时,都会被替换成执行如下invoke方法
* 其中:
* proxy--代表动态代理对象
* method--代表正在执行的方法
* args--代表执行代理对象方法时传入的实参
*/
public Object invoke(Object proxy,Method method,Object[] args){
System.out.println("正在执行的方法:"+method);
if(args!=null){
System.out.println("下面是执行该方法时传入的实参:");
for(Object val:args){
System.out.println(val);
}
}else{
System.out.println("调用该方法无须实参");
}
return null;
}
}
public class ProxyTest { public static void main(String[] args) throws Exception{ //创建一个InvocationHandler对象 InvocationHandler handler=new MyInvokationHandler(); //使用指定的InvocationHanlder来生成一个动态代理对象 PersonPro p=(PersonPro)Proxy.newProxyInstance(PersonPro.class.getClassLoader(), new Class[]{PersonPro.class}, handler); //调用动态代理对象的walk()方法和sayHello()方法 p.walk(); p.sayHello("luck"); } } interface PersonPro{ void walk(); void sayHello(String name); } class MyInvokationHandler implements InvocationHandler{ /* * 执行动态代理对象的所有方法时,都会被替换成执行如下invoke方法 * 其中: * proxy--代表动态代理对象 * method--代表正在执行的方法 * args--代表执行代理对象方法时传入的实参 */ public Object invoke(Object proxy,Method method,Object[] args){ System.out.println("正在执行的方法:"+method); if(args!=null){ System.out.println("下面是执行该方法时传入的实参:"); for(Object val:args){ System.out.println(val); } }else{ System.out.println("调用该方法无须实参"); } return null; } }
上面程序中提供了一个Person接口,该接口中包含了walk和sayHello两个抽象方法,接着程序定义了一个简单的InvocationHandler实现类,定义该实现类时需要重写invoke方法----执行代理对象所有方法执行时将会替换成执行此invoke方法.
从运行结果中可以看出,不管程序执行代理对象的walk()方法,还是执行代理对象的sayHello()方法,实际上都是执行InvocationHandler对象的invoke()方法.
下一篇文章将实现Spring中AOP的动态代理的demo
相关文章推荐
- Java JDK动态代理的基本原理详细介绍
- 动态代理(一)---JDK动态代理
- java实现JDK动态代理
- Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM)
- JDK动态代理
- JDK动态代理实现原理
- Spring AOP详解 、 JDK动态代理、CGLib动态代理
- 聊聊动态代理:jdk、cglib、javassist
- 你一定能看懂的JDK动态代理
- 最详细的代理讲解--JDK动态代理和cglib代理
- jdk动态代理如此简单
- JAVA JDK CGLIB 动态代理 比较
- java动态代理(JDK和cglib)
- java_IO,反射机制,jdk动态代理
- JDK动态代理的实现及原理
- JDK解构 - Java中的引用和动态代理的实现
- JDK动态代理
- 【动态代理】从源码实现角度剖析JDK动态代理
- JDK动态代理的深度解析
- Spring学习之动态代理(JDK动态代理和CGLIB动态代理)