jdk动态代理基本实现

动态代理的实现主要包括三部分:

接口:声明业务方法

代理对象:真正对象的代理对象,通过真正对象的业务方法实现抽象类或接口的方法,并可附加自己的业务逻辑

真是对象:实现接口的方法,供代理对象调用

jdk中创建动态代理主要通过java.lang.reflect.Proxy类的

newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException)方法。它的第一个参数是真实对象的类加载器,可以通过对象的.getClass().getClassLoader()获取

第二个参数是真实对象实现的接口,可以通过对象的.getClass().getInterfaces()获取

第三个参数是实现InvocationHandler接口的对象,通过api可知InvocationHandler是代理实例的调用处理程序 实现的接口,主要用于监听代理对象调用方法来调用真实对象的方法,它底层采用的是观察者模式。

InvocationHandler接口是一个函数式接口,它只有一个invoke(Object proxy, Method method, Object[] args) 方法,当代理对象调用方法时,会执行此方法。它的

第一个参数是代理对象

第二个参数是真实对象要调用方法,即调用的方法对象

第三个对象是调用方法的参数

如下:

首先创建一个接口:

public interface ITarget {
	public void show();
}

真实对象实现接口:

public class Target implements ITarget {

	@Override
	public void show() {
		System.out.println("-----------------show");
	}

}

创建代理对象调用真实对象接口:

@Test
public void test1() {
	//System.out.println("------------");
	ITarget target = new Target();
	//创建代理对象
	ITarget targetProxy = (ITarget) Proxy.newProxyInstance(
			target.getClass().getClassLoader(), //真实对象的类加载器
			target.getClass().getInterfaces(), //真实对象实现的接口
			(Object proxy, Method method, Object[] args) -> {
				System.out.println("附加的功能...日志、开启事务等等");
				Object object =  method.invoke(target, args);//调用真实目标方法,参数1为真实对象
				System.out.println("附加的功能...结束时间、提交事务等等");
				return object;
			}
	);
	targetProxy.show();//代理对象调用方法。
}

当代理对象调用show()方法时,会执行InvocationHandler实现类中的invoke方法,并将代理对象传入invoke方法proxy参数,将要执行的方法传入method,并将方法参数传入args。而此时invoke方法真正调用真实对象方法的是method.invoke方法(第一个参数为真实对象,第二个参数为真实对象方法的参数,即InvocationHandler实现类中的invoke方法中的args),而在执行此方法是可以在此方法前后添加附加功能。当然在执行method.invoke一般会用Object来接收返回值,这样当真实对象执行后有返回值时这样代理对象也会接收到返回值

猜你喜欢

转载自blog.csdn.net/u010689849/article/details/85013566