Java动态代理

在看Spring视频教程的时候看到有关动态代理的,之前没了解过,通过查API文档和网上一些别人写的东西好好了解了一下,才有了这篇文章

文章参考:http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/


动态代理可以为其他对象提供一种代理以控制对这个对象的访问,相当于在客户端和目标对象之间建立一座桥梁,这样客户端就可以通过这座桥梁(代理对象)来访问被代理类的方法,Java中动态代理主要用到 InvocationHandler接口和 Proxy类,InvocationHandler接口只有一个invoke()方法,我们编写的代理类都要实现这个接口,而Proxy类主要有四个静态方法,其详细情况可以查看API文档或源码,下面用具体代码实现我们的动态代理:

1、先创建一个接口:

public interface MethodDAO {
	public void method1();
	public void method2();
}
2、实现接口,重写方法:

public class MethodDAOImpl implements MethodDAO {
	@Override
	public void method1() {
		System.out.println("方法1");
	}
	@Override
	public void method2() {
		System.out.println("方法2");
	}
}
3、编写我们自己的代理类:

public class MethodDAOImplProxy implements InvocationHandler {
	private MethodDAO methodDAO = new MethodDAOImpl(); 
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("可在此处加入调用前要执行的逻辑···");
		//调用我们写的方法
		Object object = method.invoke(methodDAO, args);
		System.out.println("可在此处加入调用后要执行的逻辑···");
		return object;
	}
}

4、客户端,测试代理:

public class TestMethodDAOImplProxy {
	public static void main(String[] args) {
		InvocationHandler handler = new MethodDAOImplProxy();
		//返回代理类实例,这样就可以通过代理类的对象调用MethodDAO中的方法
		MethodDAO methodDAO =  (MethodDAO) Proxy.newProxyInstance(MethodDAO.class.getClassLoader(),
				new Class[]{MethodDAO.class}, handler); 
		methodDAO.method1();
		methodDAO.method2();
	}
	
//	这里将newProxyInstance() 的源码贴出来,方便理解,想更详细的了解其运行过程是怎样代理的,还是在Debug下调试运行,
//	我也是调试很多次才弄懂的,其中用到很多反射的东西
//	public static Object newProxyInstance(ClassLoader loader,
//			  Class<?>[] interfaces,InvocationHandler h)
//				throws IllegalArgumentException {
//		if (h == null) {
//			throw new NullPointerException();
//		}
		// 获得与制定类装载器和一组接口相关的代理类类型对象
//		Class cl = getProxyClass(loader, interfaces);
	
		// 通过反射获取构造函数对象并生成代理类实例
//		try {
//			Constructor cons = cl.getConstructor(constructorParams);
//			return (Object) cons.newInstance(new Object[] { h });
//		} catch (NoSuchMethodException e) {
//			throw new InternalError(e.toString());
//		} catch (IllegalAccessException e) {
//			throw new InternalError(e.toString());
//		} catch (InstantiationException e) {
//			throw new InternalError(e.toString());
//		} catch (InvocationTargetException e) {
//			throw new InternalError(e.toString());
//		}
//	}

}

运行结果:

可在此处加入调用前要执行的逻辑···
方法1
可在此处加入调用后要执行的逻辑···
可在此处加入调用前要执行的逻辑···
方法2
可在此处加入调用后要执行的逻辑···


从结果可以看出,在每次调用方法时都会调用invoke()。

使用动态代理的好处是显而易见的,比如我们想在调用method1()之前或者之后加一些判断或者逻辑方法,这时我们只要修改代理类的代码,而不用修改客户端的代码






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值