Java 反射之JDK动态代理

         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个通用方法======