JDK动态代理

借助于Java提供的Proxy和InvocationHandler,可以实现在运行时生成动态代理的功能,而动态代理对象可作为目标对象使用,而且增加了目标对象的功能。下面我们将要实现一个类似于JDK的动态代理。设计的UML类图如下。


下面笔者给出的实现方法。

1)        提供一个Dog接口。

public interface Dog
{
	// info()方法声明
	void info();
	// run()方法声明
	void run();
}

2)        GunDog的类。

public class GunDog implements Dog
{
	//info方法实现,仅仅打印一个字符串
	public void info()
	{
		System.out.println("我是一只猎狗");
	}
	//run方法实现,仅仅打印一个字符串
	public void run()
	{
		System.out.println("我奔跑迅速");
	}
}

3)        下面提供一个TxUtil类,这个类通常称为拦截器,该类包含两个方法,分别是开始事务和提交事务。

 public class TxUtil
{
	// 第一个拦截器方法:模拟事务开始
	public void beginTx()
	{
		System.out.println("=====模拟开始事务=====");
	}
	// 第二个拦截器方法:模拟事务结束
	public void endTx()
	{
		System.out.println("=====模拟结束事务=====");
	}
}

4)        JDK动态代理的关键在于下面的MyInvokationHandler类,该类是一个InvocationHandler实现类,该实现类的invoke方法将会作为代理对象的方法实现。

public class MyInvokationHandler
	implements InvocationHandler
{
	// 需要被代理的对象
	private Object target;
	public void setTarget(Object target)
	{
		this.target = target;
	}
	// 执行动态代理对象的所有方法时,都会被替换成执行如下的invoke方法
	public Object invoke(Object proxy, Method method, Object[] args)
		throws Exception
	{
		TxUtil tx = new TxUtil();
		// 执行TxUtil对象中的beginTx()。
		tx.beginTx();
		// 以target作为主调来执行method方法
		Object result = method.invoke(target , args);
		// 执行TxUtil对象中的endTx()。
		tx.endTx();
		return result;
	}
}

 

5)        下面再为程序提供一个MyProxyFactory类,该对象专门为指定的target生成动态代理实例。

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

6)        写个测试类。

public class Test
{
	public static void main(String[] args)
		throws Exception
	{
		// 创建一个原始的GunDog对象,作为target
		Dog target = new GunDog();
		// 以指定的target来创建动态代理
		Dog dog = (Dog)MyProxyFactory.getProxy(target);
		// 调用代理对象的info()和run()方法
		dog.info();
		dog.run();
	}
}

7)        执行结果。

JDK动态代理_第1张图片

8)        执行步骤。

                        i.             创建TxUtil实例。

                      ii.             执行TxUtil实例的beginTx()方法。

                     iii.             使用反射以target作为调用执行info()方法。

                     iv.             执行TxUtil实例的endTx()方法。












你可能感兴趣的:(java,设计模式,jsp,UML,Web应用)