Java动态代理之JDK

昨天和今天学习了Java的动态代理。现在让我总结一下。

首先先让我们谈一下一种设计模式:  代理模式

详情请看:http://blog.youkuaiyun.com/hwb1992/article/details/20538921

现在让我们来讨论一下动态代理

代码上,记得看注释哦

package edu.fjnu.cs.hwb.proxypattern;

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


interface MyOperation //定义了所有的接口方法
{
	void say(String name);
}

class MyOperationImpl implements MyOperation
{
	@Override
	public void say(String name) {
		// TODO Auto-generated method stub
		System.out.println("MyOperationImpl"+name);
	}
}


class MyInvocationHandler implements InvocationHandler
{
	private Object obj;
	public MyInvocationHandler(Object obj)
	{
		this.obj = obj;
		//其实,我在这里也有个疑问,为什么要把目标对象放在这里面,我试过不用这句话,然后执行的话会报错,内容就是
		/*
		 * 	at edu.fjnu.cs.hwb.proxypattern.$Proxy0.say(Unknown Source)
				at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
				at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
				at java.lang.reflect.Method.invoke(Method.java:597)
				at edu.fjnu.cs.hwb.proxypattern.MyInvocationHandler.invoke(JDKProxy.java:35)
				从中我推测出,JDK不知道目标对象是谁,因此这句话就是设置目标对象
				当我添加这句话之后,我调试运行,发现那个invoke的参数proxy居然和我的属性obj是一模一样的,但是没有添加这句话之前就不是了 。 
				但是如果我下面写得是 method.invoke(proxy, args); 那么还是会报错!!我觉得好奇怪。obj和proxy不是指向同一个对象吗?
				
				希望有大神可以指教我一下
		 */
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("before");
		Object result = method.invoke(obj, args);//调用的是目标类的方法    第一个参数是目标对象的引用
		System.out.println("end");
		return result ;
	}	
}

public class JDKProxy
{
	public static void main(String[] args)
	{
		MyOperation myoperation = new MyOperationImpl();//产生目标类
		MyInvocationHandler myhandler = new MyInvocationHandler(myoperation);//产生一个InvocationHandler的子类对象,并且重写invoke方法
                //以及在其中添加了目标类引用  	
		MyOperation m = 
           (MyOperation) Proxy.newProxyInstance(myoperation.getClass().getClassLoader(),myoperation.getClass().getInterfaces(),myhandler);
		//产生了一个代理类,第一个参数表示的是用哪个类加载器
		//第二个参数表示目标类的所有接口方法
		//第三个参数表示我会调用这个参数的invoke方法
		m.say("test");
	
		/**
		 * 结果是:
		 * before
			MyOperationImpltest
			end
		 */
		
		/**
		 * 让我们来看一下具体的东西吧、这个 m  到底是什么东西
		 */
		System.out.println(m.getClass().getName());
		//edu.fjnu.cs.hwb.proxypattern.$Proxy0    这意味着m指向的对象是一个Proxy子类
		System.out.println(m.getClass().getSuperclass().getName());
		//java.lang.reflect.Proxy   m指向的对象的父类是Proxy
		System.out.println(m.getClass().getInterfaces()[0].getName());
		//edu.fjnu.cs.hwb.proxypattern.MyOperation     这意味着m指向的类所实现的第一个接口的接口类
		//综上所述   通过	Proxy.newProxyInstance(loader, interfaces, h) 会利用第一个参数类加载器动态的产生一个Proxy的子类
           //并且实现了参数二的所有接口方法,当产生的对象调用了某个接口方法时,就会拦截下来,去调用h所拥有invoke方法
		//因此,这就有个缺陷,就是jdk的动态代理必须是接口的,如果一个类没有实现接口,那么就没有办法用动态代理,cglib的出现弥补了这个缺陷
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值