您的位置:首页 > 编程语言 > Java开发

Java 反射之JDK动态代理

2015-04-13 17:19 417 查看
Proxy提供用于创建动态代理类和代理对象的静态方法,它也是所有动态代理类的父类。如果我们在程序中为一个或多个接口动态地生成实现类,就可以使用Proxy来创建动态代理类;如果需要为一个或多个接口动态的创建实例,也可以使用Proxy来创建动态代理实例。

Proxy提供了如下两个方法来创建动态代理类和动态代理类:

(1)、static Class<?> getProxyClass(ClassLoader loader,Class<?> ...interfaces) : 创建一个动态代理类所对应的Class对象,该代理类将实现interfaces所指定的多个接口。第一个ClassLoader指定生成动态代理类的类加载器。

(2)、static Object newProxyInstance(ClassLoader loader,Class<?> interfaces, InvocationHandler h) :直接创建一个动态代理对象,该代理对象的实现类实现了interfaces指定的系列接口,执行代理对象的每个方法时都会被替换成执行 InvocationHandler对象的invoke方法。

实际上,即使采用第一种方式获取了一个动态代理类之后,当程序需要通过该代理类来创建对象时一样需要传入一个InvocationHandler对象。也就是说,系统生成的每个代理对象都有一个与之关联的InvocationHandler对象。

下面是AOP动态代理的实现:

在方法前后加入一写通用方法,比如项目中的日志记录。

Dog.java

package com.reflect.proxy;

public interface Dog {
public void info();
public void run();
}
GunDog.java

package com.reflect.proxy;

public class GunDog implements Dog {

@Override
public void info() {
System.out.println("我是一只猎狗");
}

@Override
public void run() {
System.out.println("我奔跑迅速");
}

}


DogUtil.java

package com.reflect.proxy;

public class DogUtil {

public void method1(){
System.out.println("=====模拟第1个通用方法======");
}

public void method2(){
System.out.println("=====模拟第2个通用方法======");
}

}
借助于Proxy和InvocationHandler就可以实现:当程序调用info()方法和run()方法时,系统就可以“自动” 将method1()和method2() 两个通用方法插入info()和run()犯法

package com.reflect.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MyInvocationHandler implements InvocationHandler {

//需要被代理的对象
private Object target;

public void setTarget(Object target){
this.target=target;
}

//指定动态代理的所有方法时,都会替换成执行如下的invoke方法
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
DogUtil du=new DogUtil();

//执行DogUtil中的method1
du.method1();
//以target为主掉来执行method方法
Object result=method.invoke(target, args);
System.out.println(result);
//执行DogUtil中的Method2
du.method2();
return result;
}

}


为指定的target生成代理类.

package com.reflect.proxy;

import java.lang.reflect.Proxy;

public class MyProxyFactory {

//为指定target生成动态代理对象
public static Object getProxy(Object target){
MyInvocationHandler handler=new MyInvocationHandler();
//为MyInvotationHandler设置target对象
handler.setTarget(target);
//创建并返回一个动态代理
return  Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler);
}
}


测试类

package com.reflect.proxy;

public class Test {

public static void main(String[] args) {

//创建一个原始的GunDog对象,作为target
Dog target=new GunDog();
//以指定的target创建动态代理
Dog dog=(Dog) MyProxyFactory.getProxy(target);
dog.info();
dog.run();
}
}


输出:

=====模拟第1个通用方法======
我是一只猎狗
=====模拟第2个通用方法======

=====模拟第1个通用方法======
我奔跑迅速
=====模拟第2个通用方法======
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: