Java动态署理的理解
Java动态代理的理解Realsubject.java代码 //具体角色??? ?? public?class?RealSubject?implements?Subject
Java动态代理的理解
Realsubject.java代码
//具体角色??? ?? public?class?RealSubject?implements?Subject??? ?? {??? ?? ?? ?? ????public?RealSubject()??? ?? ????{??? ?? ????}??? ?? ?? ?? ????public?void?request()??? ?? ????{??? ?? ????????System.out.println("真正做事的。");??? ?? ????}??? ?? }??
?
Dynamicsubject.java代码 //代理处理器??? ??
/**?? ?? ?*?该代理类的内部属性为Object类,实际使用时通过该类的构造函数DynamicSubject(Object?obj)对其赋值;?? ?? ?*?此外,在该类还实现了invoke方法,该方法中的?method.invoke(sub,args);?? ?? ?*?其实就是调用被代理对象的将要被执行的方法,方法参数sub是实际的被代理对象,?? ?? ?*?args为执行被代理对象相应操作所需的参数。?? ?? ?*?通过动态代理类,我们可以在调用之前或之后执行一些相关操作?? ?? ?*/?? ?? ?? ?? public?class?DynamicSubject?implements?InvocationHandler??? ?? {??? ?? ????private?Object?sub;??? ?? ?? ?? ????public?DynamicSubject()??? ?? ????{??? ?? ????}??? ?? ?? ?? ????public?DynamicSubject(Object?obj)??? ?? ????{??? ?? ????????sub?=?obj;??? ?? ????}??? ?? ?? ?? ????public?Object?invoke(Object?proxy,?Method?method,?Object[]?args)?throws?Throwable??? ?? ????{??? ?? ????????System.out.println("调用前"?+?method);??? ?? ?? ?? ????????method.invoke(sub,?args);??? ?? ?? ?? ????????System.out.println("调用后?"?+?method);??? ?? ?? ?? ????????return?null;??? ?? ????}??? ?? }?????
Client.java代码
//客户端??? ?? public?class?Client??? ?? {??? ?? ????static?public?void?main(String[]?args)?throws?Throwable??? ?? ????{??? ?? ?? ?? ????????RealSubject?rs?=?new?RealSubject();?//?在这里指定被代理类??? ?? ????????InvocationHandler?ds?=?new?DynamicSubject(rs);??? ?? ????????Class<?>?cls?=?rs.getClass();??? ?? ?? ?? ????????//?以下是一次性生成代理??? ?? ?? ?? ????????Subject?subject?=?(Subject)?Proxy.newProxyInstance(??? ?? ????????????????cls.getClassLoader(),?cls.getInterfaces(),?ds);??? ?? ?? ?? ????????subject.request();??? ?? ????}??? ?? }????
???????? 这个程序中把静态代理类的抽象类改变为一个接口,而实际类实现这个接口。是因为Proxy类的newProxyInstance方法传入需要提供一个接口,这个是Java动态代理框架给我们设计好的了。本例的ProxySubject类实现了InvocationHandler接口及实现invoke方法,并且提供一个带参数的构造方法,通过Client类动态的调用真实类。
?
???????? Client类通过DynamicSubject类生成真实类的代理对象,并经由Proxy类的newProxyInstance方法实现生成“一个能做真实类做的事的代理”,并由该代理直接调用真实类所具有的方法。
? ?
???????? 下面这个类作为参考,代码如下:
????????? Vectorproxy.java代码
import?java.lang.reflect.InvocationHandler;??? ?? import?java.lang.reflect.Method;??? ?? import?java.lang.reflect.Proxy;??? ?? import?java.util.List;??? ?? import?java.util.Vector;??? ?? ?? ?? public?class?VectorProxy?implements?InvocationHandler??? ?? {??? ?? ????private?Object?proxyobj;??? ?? ?? ?? ????public?VectorProxy(Object?obj)??? ?? ????{??? ?? ????????proxyobj?=?obj;??? ?? ????}??? ?? ?? ?? ????public?static?Object?factory(Object?obj)??? ?? ????{??? ?? ????????Class<?>?cls?=?obj.getClass();??? ?? ?? ?? ????????return?Proxy.newProxyInstance(cls.getClassLoader(),??? ?? ????????????????cls.getInterfaces(),?new?VectorProxy(obj));??? ?? ????}??? ?? ?? ?? ????public?Object?invoke(Object?proxy,?Method?method,?Object[]?args)??? ?? ????????????throws?Throwable??? ?? ????{??? ?? ????????System.out.println("before?calling?"?+?method);??? ?? ?? ?? ????????if?(args?!=?null)??? ?? ????????{??? ?? ????????????for?(int?i?=?0;?i?<?args.length;?i++)??? ?? ????????????{??? ?? ????????????????System.out.println(args[i]?+?"");??? ?? ????????????}??? ?? ????????}??? ?? ????????Object?object?=?method.invoke(proxyobj,?args);??? ?? ?? ?? ????????System.out.println("after?calling?"?+?method);??? ?? ????????return?object;??? ?? ????}??? ?? ?? ?? ????@SuppressWarnings("unchecked")??? ?? ????public?static?void?main(String[]?args)??? ?? ????{??? ?? ????????List<String>?v?=?(List<String>)?factory(new?Vector<String>(10));??? ?? ?? ?? ????????v.add("New");??? ?? ????????v.add("York");??? ?? ????????System.out.println(v);??? ?? ?? ?? ????????v.remove(0);??? ?? ????????System.out.println(v);??? ?? ????}??? ?? }????
????????? 下面也是一个演示程序,作为扩展知识用,一共五个类,在同一包下,代码如下:
?
?????????? 五个类Foo.java, FooImpl.java, FooImpl2.java, CommonInvocationHandler.java和Demo.java。
Foo.java代码
public?interface?Foo??? ?? {??? ?? ????void?doAction();??? ?? }?????
Fooimpl.java代码
public?class?FooImpl?implements?Foo??? ?? {??? ?? ????public?FooImpl()??? ?? ????{??? ?? ????}??? ?? ?? ?? ????public?void?doAction()??? ?? ????{??? ?? ????????System.out.println("in?FooImp1.doAction()");??? ?? ????}??? ?? }???
?
Fooimpl2.java代码
public?class?FooImpl2?implements?Foo??? ?? {??? ?? ????public?FooImpl2()??? ?? ????{??? ?? ????}??? ?? ?? ?? ????public?void?doAction()??? ?? ????{??? ?? ????????System.out.println("in?FooImp2.doAction()");??? ?? ????}??? ?? }??
?
Commoninvocationhandler.java代码
import?java.lang.reflect.InvocationHandler;??? ?? import?java.lang.reflect.Method;??? ?? ?? ?? public?class?CommonInvocationHandler?implements?InvocationHandler??? ?? {??? ?? ?? ?? ????//?动态执行对象,需要回调的对象??? ?? ????private?Object?target;??? ?? ?? ?? ????//?支持构造子注射??? ?? ????public?CommonInvocationHandler()??? ?? ????{??? ?? ?? ?? ????}??? ?? ?? ?? ????//?支持构造子注射??? ?? ????public?CommonInvocationHandler(Object?target)??? ?? ????{??? ?? ????????setTarget(target);??? ?? ????}??? ?? ?? ?? ????/**?? ?? ?????*??? ?? ?????*?采用setter方法注射?? ?? ?????*??? ?? ?????*?@param?target?? ?? ?????*??? ?? ?????*/?? ?? ????public?void?setTarget(Object?target)??? ?? ????{??? ?? ????????this.target?=?target;??? ?? ????}??? ?? ?? ?? ????/**?? ?? ?????*??? ?? ?????*?调用proxy中指定的方法method,并传入参数列表args?? ?? ?????*??? ?? ?????*?@param?proxy?? ?? ?????*????????????代理类的类型,例如定义对应method的代理接口?? ?? ?????*??? ?? ?????*?@param?method?? ?? ?????*????????????被代理的方法?? ?? ?????*??? ?? ?????*?@param?args?? ?? ?????*????????????调用被代理方法的参数?? ?? ?????*??? ?? ?????*?@return?? ?? ?????*??? ?? ?????*?@throws?java.lang.Throwable?? ?? ?????*??? ?? ?????*/?? ?? ????public?Object?invoke(Object?proxy,?Method?method,?Object[]?args)?throws?Throwable??? ?? ????{??? ?? ????????return?method.invoke(target,?args);??? ?? ????}??? ?? }????
Demo.java代码
import?java.lang.reflect.Proxy;??? ?? ?? ?? public?class?Demo??? ?? {??? ?? ????public?static?void?main(String[]?args)??? ?? ????{??? ?? ?? ?? ????????//?1.通用的动态代理实现??? ?? ?? ?? ????????CommonInvocationHandler?handler?=?new?CommonInvocationHandler();??? ?? ?? ?? ????????Foo?f;??? ?? ?? ?? ????????//?2.接口实现1??? ?? ?? ?? ????????handler.setTarget(new?FooImpl());??? ?? ?? ?? ????????//?方法参数说明:代理类、代理类实现的接口列表、代理类的处理器??? ?? ?? ?? ????????//?关联代理类、代理类中接口方法、处理器,当代理类中接口方法被调用时,会自动分发到处理器的invoke方法??? ?? ?? ?? ????????//?如果代理类没有实现指定接口列表,会抛出非法参数异常??? ?? ?? ?? ????????f?=?(Foo)?Proxy.newProxyInstance(Foo.class.getClassLoader(),??? ?? ?? ?? ????????new?Class[]?{?Foo.class?},??? ?? ?? ?? ????????handler);??? ?? ?? ?? ????????f.doAction();??? ?? ?? ?? ????????//?3.接口实现2??? ?? ?? ?? ????????handler.setTarget(new?FooImpl2());??? ?? ?? ?? ????????f?=?(Foo)?Proxy.newProxyInstance(Foo.class.getClassLoader(),??? ?? ?? ?? ????????new?Class[]?{?Foo.class?},??? ?? ?? ?? ????????handler);??? ?? ?? ?? ????????f.doAction();??? ?? ????}??? ?? }??