Java动态代理模式怎么实现

Java动态代理模式怎么实现

这篇文章主要介绍“Java动态代理模式怎么实现”,在日常操作中,相信很多人在Java动态代理模式怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java动态代理模式怎么实现”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

1. Overview

Java在java.lang.reflect包下,定义了自己的代理。利用这个包下的类,我们可以在运行时动态地创建一个代理类,实现一个或多个接口。并将方法的调用转发到你所指定的类。因为实际代理是在运行时创建的,所以称为:动态代理。

Proxy:完全由java产生的,而且实现了完整的subject接口。

InvocationHandler:Proxy上的任何方法调用都会被传入此类,InvocationHandler控制对RealSubject的访问。

因为Java已经帮助我们创建了Proxy类,我们需要有办法告诉Proxy类你要做什么,我们不能像以前一样把代码写入到Proxy类中,因为Proxy类不是我们实现的。那么我们应该放在哪里?放在InvocationHandler类中,InvocationHandler类是响应代理的任何调用。我们可以吧InvocationHandler想成是代理收到方法调用后,请求做实际工作的对象。

2. java.lang.reflect.InvocationHandler

被代理实例所实现的一个接口,内部只有一个invoke()方法,签名如下;

Java代码

publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)

当代理的方法被调用的时候,代理就会把这个调用转发给InvocationHandler,也就会调用它的invoke()方法。

3. java.lang.reflect.Proxy

提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类,我们经常使用的静态方式是:

Java代码

newProxyInstance(ClassLoaderloader,Class[]interfaces,InvocationHandlerh)

4. 示例:

情形:自己可以查看修改姓名性别,但是不能修改rate。他人可以查看姓名,性别以及修改rate,但是不能修改姓名性别。

4.1 定义一个接口:

Java代码

publicinterfacePerson{StringgetName();StringgetGender();voidsetName(Stringname);voidsetGender(Stringgender);voidsetRate(intrate);intgetRate();}

4.2 定义实现Person接口类

Java代码

publicclassPersonImplimplementsPerson{Stringname;Stringgender;Stringinterests;intrate;publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}publicStringgetGender(){returngender;}publicvoidsetGender(Stringgender){this.gender=gender;}publicStringgetInterests(){returninterests;}publicvoidsetInterests(Stringinterests){this.interests=interests;}publicintgetRate(){returnrate;}publicvoidsetRate(intrate){this.rate=rate;}

4.3 定义OwnerInvocationHandler类,表示如果为本人,则可以进行修改查看姓名性别。

Java代码

publicclassOwnerInvocationHandlerimplementsInvocationHandler{privatePersonpersonBean;publicOwnerInvocationHandler(PersonpersonBean){this.personBean=personBean;}@OverridepublicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsIllegalAccessException{try{if(method.getName().startsWith("get")){//如果方法名为get,就调用person类内的get相应方法returnmethod.invoke(personBean,args);}elseif(method.getName().equals("setRate")){//如果方法是setRate,则抛出异常thrownewIllegalAccessException("accessdeny");}elseif(method.getName().startsWith("set")){//如果为set,就调用person类内的set相应方法returnmethod.invoke(personBean,args);}else{System.out.println("nonmethodinvoke");}}catch(InvocationTargetExceptione){e.printStackTrace();}returnnull;}}

4.4 定义NonInvocationHandler类,表示如果不为本人,则可以进行查看姓名性别和修改rate。

Java代码

publicclassNonInvocationHandlerimplementsInvocationHandler{//privatePersonperson;publicNonInvocationHandler(Personperson){this.person=person;}@OverridepublicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{if(method.getName().startsWith("setRate")){returnmethod.invoke(person,args);}elseif(method.getName().startsWith("get")){returnmethod.invoke(person,args);}else{System.out.println("nonmethodinvoke");returnnull;}}}

4.5 测试类MyDynamicProxy

Java代码

publicclassMyDynamicProxy{publicPersongetOwnerPersonBeanProxy(Personperson){return(Person)Proxy.newProxyInstance(person.getClass().getClassLoader(),person.getClass().getInterfaces(),newOwnerInvocationHandler(person));}publicPersongetNonPersonBeanProxy(Personperson){return(Person)Proxy.newProxyInstance(person.getClass().getClassLoader(),person.getClass().getInterfaces(),newNonInvocationHandler(person));}publicstaticvoidmain(String[]args){MyDynamicProxymdp=newMyDynamicProxy();mdp.test();}publicvoidtest(){//Personperson=getPersonBeanFromDB1();PersonpersonProxy=getOwnerPersonBeanProxy(person);System.out.println(personProxy.getName());try{personProxy.setRate(2);}catch(Exceptione){System.out.println("cannotsetRate");}//Personperson1=getPersonBeanFromDB1();PersonpersonProxy2=getNonPersonBeanProxy(person1);System.out.println(personProxy2.getName());personProxy2.setRate(2);System.out.println(personProxy2.getRate());}privatePersongetPersonBeanFromDB1(){Personpb=newPersonImpl();pb.setName("remy");pb.setGender("girl");pb.setRate(1);returnpb;}

输出结果:

Java代码

remycannotsetRateremy2

到此,关于“Java动态代理模式怎么实现”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

发布于 2022-01-06 23:29:43
收藏
分享
海报
0 条评论
27
上一篇:Java平台的构架与版本有哪些 下一篇:Java中Struts2处理流程是怎样的
目录

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码