摘要:\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Ch1\u003E\u003Cstrong\u003E静态代理实现\u003C\u002Fstrong\u003E\u003C\u002Fh1\u003E\u003Cdiv class=\"pgc-img\"\u003E\u003Cimg src=\"http:\u002F\u002Fp1.pstatp.com\u002Flarge\u002Fpgc-image\u002F94969e6e0cd84f749f3259fd63a301f1\" img_width=\"300\" img_height=\"240\" alt=\"程序员进阶干货——深入理解静态代理与JDK动态代理\" inline=\"0\"\u003E\u003Cp class=\"pgc-img-caption\"\u003E\u003C\u002Fp\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E\u003Cstrong\u003E静态代理三步走\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E1. 定义业务接口\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cpre\u003Epublic interface HelloService {\u003Cbr\u003E\tString hello( String name )。\u003Cstrong\u003E动态代理主要分为JDK动态代理和cglib动态代理两大类,本文主要对JDK动态代理进行探讨\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003EJDK动态代理使用步骤\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Cstrong\u003E创建被代理的接口和类\u003C\u002Fstrong\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cpre\u003E\u002F\u002F 抽象主题角色\u003Cbr\u003Epublic interface HelloService {\u003Cbr\u003E\tString hello( String name )。

"\u003Cdiv\u003E\u003Ch1\u003E\u003Cstrong\u003E代理模式\u003C\u002Fstrong\u003E\u003C\u002Fh1\u003E\u003Cdiv class=\"pgc-img\"\u003E\u003Cimg src=\"http:\u002F\u002Fp1.pstatp.com\u002Flarge\u002Fpgc-image\u002F043385fecbbb46508e5a7959e5034ae3\" img_width=\"500\" img_height=\"354\" alt=\"程序员进阶干货——深入理解静态代理与JDK动态代理\" inline=\"0\"\u003E\u003Cp class=\"pgc-img-caption\"\u003E\u003C\u002Fp\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E\u003Cstrong\u003E简介\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003E代理模式是一种常用的设计模式,在AOP、RPC等诸多框架中均有它的身影\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E代理对象存在的价值主要用于拦截对真实业务对象的访问;\u003C\u002Fli\u003E\u003Cli\u003E代理对象具有和目标对象(真实业务对象)实现共同的接口或继承于同一个类;\u003C\u002Fli\u003E\u003Cli\u003E代理对象是对目标对象的增强,以便对消息进行预处理和后处理。\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E\u003Cstrong\u003E定义与结构\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E定义:\u003C\u002Fstrong\u003E为其他对象提供一种代理以控制对这个对象的访问。\u003C\u002Fp\u003E\u003Cdiv class=\"pgc-img\"\u003E\u003Cimg src=\"http:\u002F\u002Fp3.pstatp.com\u002Flarge\u002Fpgc-image\u002F0e2d7e1ed96243a6869124c6744e7397\" img_width=\"915\" img_height=\"304\" alt=\"程序员进阶干货——深入理解静态代理与JDK动态代理\" inline=\"0\"\u003E\u003Cp class=\"pgc-img-caption\"\u003E\u003C\u002Fp\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E代理模式主要包含三个角色,即抽象主题角色(Subject)、委托类角色(被代理角色,Proxied)以及代理类角色(Proxy),如上图所示\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E抽象主题角色:可以是接口,也可以是抽象类;\u003C\u002Fli\u003E\u003Cli\u003E委托类角色:真实主题角色,业务逻辑的具体执行者;\u003C\u002Fli\u003E\u003Cli\u003E代理类角色:内部含有对真实对象RealSubject的引用,负责对真实主题角色的调用,并在真实主题角色处理前后做预处理和后处理。\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Ch1\u003E\u003Cstrong\u003E静态代理实现\u003C\u002Fstrong\u003E\u003C\u002Fh1\u003E\u003Cdiv class=\"pgc-img\"\u003E\u003Cimg src=\"http:\u002F\u002Fp1.pstatp.com\u002Flarge\u002Fpgc-image\u002F94969e6e0cd84f749f3259fd63a301f1\" img_width=\"300\" img_height=\"240\" alt=\"程序员进阶干货——深入理解静态代理与JDK动态代理\" inline=\"0\"\u003E\u003Cp class=\"pgc-img-caption\"\u003E\u003C\u002Fp\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E\u003Cstrong\u003E静态代理三步走\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E1. 定义业务接口\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cpre\u003Epublic interface HelloService {\u003Cbr\u003E\tString hello( String name );\u003Cbr\u003E\u003Cbr\u003E\tString hi( String msg );\u003Cbr\u003E}\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003E\u003Cstrong\u003E2.实现业务接口\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cpre\u003Epublic class HelloServiceImpl implements HelloService {\u003Cbr\u003E\t@Override\u003Cbr\u003E\tpublic String hello( String name )\u003Cbr\u003E\t{\u003Cbr\u003E\t\treturn(\"Hello \" + name);\u003Cbr\u003E\t}\u003Cbr\u003E\u003Cbr\u003E\t@Override\u003Cbr\u003E\tpublic String hi( String msg )\u003Cbr\u003E\t{\u003Cbr\u003E\t\treturn(\"Hi, \" + msg);\u003Cbr\u003E\t}\u003Cbr\u003E}\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003E\u003Cstrong\u003E3.理类并实现业务接口\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cpre\u003Epublic class HelloServiceProxy implements HelloService {\u003Cbr\u003E\tprivate HelloService helloService;\u003Cbr\u003E\tpublic HelloServiceProxy( HelloService helloService )\u003Cbr\u003E\t{\u003Cbr\u003E\t\tthis.helloService = helloService;\u003Cbr\u003E\t}\u003Cbr\u003E\u003Cbr\u003E\t@Override\u003Cbr\u003E\tpublic String hello( String name )\u003Cbr\u003E\t{\u003Cbr\u003E\t\tSystem.out.println( \"预处理...\" );\u003Cbr\u003E\t\tString result = helloService.hello( name );\u003Cbr\u003E\t\tSystem.out.println( result );\u003Cbr\u003E\t\tSystem.out.println( \"后处理...\" );\u003Cbr\u003E\t\treturn(result);\u003Cbr\u003E\t}\u003Cbr\u003E\u003Cbr\u003E\t@Override\u003Cbr\u003E\tpublic String hi( String msg )\u003Cbr\u003E\t{\u003Cbr\u003E\t\tSystem.out.println( \"预处理...\" );\u003Cbr\u003E\t\tString result = helloService.hi( msg );\u003Cbr\u003E\t\tSystem.out.println( result );\u003Cbr\u003E\t\tSystem.out.println( \"后处理...\" );\u003Cbr\u003E\t\treturn(result);\u003Cbr\u003E\t}\u003Cbr\u003E}\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cp\u003E\u003Cstrong\u003E最后便可通过客户端进行调用\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cpre\u003Epublic class Main {\u003Cbr\u003E\tpublic static void main( String[] args )\u003Cbr\u003E\t{\u003Cbr\u003E\t\tHelloService\t\thelloService\t\t= new HelloServiceImpl();\u003Cbr\u003E\t\tHelloServiceProxy\thelloServiceProxy\t= new HelloServiceProxy( helloService );\u003Cbr\u003E\t\thelloServiceProxy.hello( \"Panda\" );\u003Cbr\u003E\t\thelloServiceProxy.hi( \"Panda\" );\u003Cbr\u003E\t}\u003Cbr\u003E}\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Ch1\u003E\u003Cstrong\u003EJDK 动态代理\u003C\u002Fstrong\u003E\u003C\u002Fh1\u003E\u003Cdiv class=\"pgc-img\"\u003E\u003Cimg src=\"http:\u002F\u002Fp1.pstatp.com\u002Flarge\u002Fpgc-image\u002Ff46ba4f9c0614c17b4413fd594646b53\" img_width=\"640\" img_height=\"480\" alt=\"程序员进阶干货——深入理解静态代理与JDK动态代理\" inline=\"0\"\u003E\u003Cp class=\"pgc-img-caption\"\u003E\u003C\u002Fp\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E动态代理可以很方便地对委托类的相关方法进行统一增强处理,如添加方法调用次数、添加日志功能等等。\u003Cstrong\u003E动态代理主要分为JDK动态代理和cglib动态代理两大类,本文主要对JDK动态代理进行探讨\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003EJDK动态代理使用步骤\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Cstrong\u003E创建被代理的接口和类\u003C\u002Fstrong\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cpre\u003E\u002F\u002F 抽象主题角色\u003Cbr\u003Epublic interface HelloService {\u003Cbr\u003E\tString hello( String name );\u003Cbr\u003E\u003Cbr\u003E\tString hi( String msg );\u003Cbr\u003E}\u003Cbr\u003E\u002F* 具体(真实)主题角色 *\u002F\u003Cbr\u003Epublic class HelloServiceImpl implements HelloService {\u003Cbr\u003E\t@Override\u003Cbr\u003E\tpublic String hello( String name )\u003Cbr\u003E\t{\u003Cbr\u003E\t\treturn(\"Hello \" + name);\u003Cbr\u003E\t}\u003Cbr\u003E\u003Cbr\u003E\t@Override\u003Cbr\u003E\tpublic String hi( String msg )\u003Cbr\u003E\t{\u003Cbr\u003E\t\treturn(\"Hi, \" + msg);\u003Cbr\u003E\t}\u003Cbr\u003E}\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cul\u003E\u003Cli\u003E\u003Cstrong\u003E实现InvocationHandler接口\u003C\u002Fstrong\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cpre\u003Epublic class MyInvocationHandler implements InvocationHandler {\u003Cbr\u003E\t\u002F* 真实业务对象 *\u002F\u003Cbr\u003E\tprivate Object target;\u003Cbr\u003E\tpublic MyInvocationHandler( Object target )\u003Cbr\u003E\t{\u003Cbr\u003E\t\tthis.target = target;\u003Cbr\u003E\t}\u003Cbr\u003E\u003Cbr\u003E\t@Override\u003Cbr\u003E\tpublic Object invoke( Object proxy, Method method, Object[] args ) throws Throwable\u003Cbr\u003E\t{\u003Cbr\u003E\t\t\u002F* 增强逻辑 *\u002F\u003Cbr\u003E\t\tSystem.out.println( \"PROXY : \" + proxy.getClass().getName() );\u003Cbr\u003E\t\t\u002F* 反射调用,目标方法 *\u002F\u003Cbr\u003E\t\tObject result = method.invoke( target, args );\u003Cbr\u003E\t\t\u002F* 增强逻辑 *\u002F\u003Cbr\u003E\t\tSystem.out.println( method.getName() + \" : \" + result );\u003Cbr\u003E\t\treturn(result);\u003Cbr\u003E\t}\u003Cbr\u003E}\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cul\u003E\u003Cli\u003E\u003Cstrong\u003E创建代理类并生成相应的代理对象\u003C\u002Fstrong\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cpre\u003E\u002F\u002F 生成代理类的class对象\u003Cbr\u003EClass<?> clazz = Proxy.getProxyClass(helloService.getClass().getClassLoader(), helloService\u003Cbr\u003E .getClass().getInterfaces());\u003Cbr\u003E\u002F\u002F 创建InvocationHandler\u003Cbr\u003EInvocationHandler myInvocationHandler = new MyInvocationHandler(helloService);\u003Cbr\u003E\u002F\u002F 获取代理类的构造器对象\u003Cbr\u003EConstructor constructor = clazz.getConstructor(new Class[] {InvocationHandler.class});\u003Cbr\u003E\u002F\u002F 反射创建代理对象\u003Cbr\u003EHelloService proxy = (HelloService)constructor.newInstance(myInvocationHandler);\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Cul\u003E\u003Cli\u003E\u003Cstrong\u003E使用代理\u003C\u002Fstrong\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cpre\u003Eproxy.hello(\"rico\");\u003Cbr\u003Eproxy.hi(\"panda\");\u003Cbr\u003E\u003C\u002Fpre\u003E\u003Ch1\u003E个人看点:\u003C\u002Fh1\u003E\u003Col\u003E\u003Cli\u003E实现动态代理的关键技术是反射;\u003C\u002Fli\u003E\u003Cli\u003E代理对象是对目标对象的增强,以便对消息进行预处理和后处理;\u003C\u002Fli\u003E\u003Cli\u003EInvocationHandler中的invoke()方法是代理类完整逻辑的集中体现,包括要切入的增强逻辑和进行反射执行的真实业务逻辑;\u003C\u002Fli\u003E\u003Cli\u003E使用JDK动态代理机制为某一真实业务对象生成代理,只需要指定目标接口、目标接口的类加载器以及具体的InvocationHandler即可。\u003C\u002Fli\u003E\u003Cli\u003EJDK动态代理的典型应用包括但不仅限于AOP、RPC、Struts2、Spring等重要经典框架。\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003C\u002Fdiv\u003E"'.slice(6, -6), groupId: '6712708293178950152
相关文章