java动态代理模式初解
package?proxypattern;
public?interface?Subject?...{
??
????public?void?dothing();
}
真实角色,实现了Subject 的dothing()方法;
package?proxypattern;
public?class?RealSubject?implements?Subject...{
???public?RealSubject()...{
?????
???}
??
???public?void?dothing()...{
???????System.out.println("Do?you?want?do.");
???}
}代理角色:
??
package?proxypattern;
public?class?ProxySubject?implements?Subject...{
????
????public?RealSubject?realSubject;
????public?ProxySubject()...{
????????
????}
????
????public?void?dothing()...{
????????predothing();
????????if(realSubject==null)...{
????????????realSubject=new?RealSubject();
????????}
????????realSubject.dothing();??//执行真实对象的dothing()方法
????????afterdothing();
????}
????
????private?void?predothing()...{
????????System.out.println("before?you?do?thing!");
????}
????private?void?afterdothing()...{
????????System.out.println("after?you?do?thing!");
????}
}
测试事例? ?? ?? ?? ???
package?proxypattern;
public?class?ProxyTest?......{
????/**?*//**?*//**?*//**
?????*?@param?args
?????*/
????public?static?void?main(String[]?args)?......{
????????
????????Subject?sub=new?ProxySubject();
????????sub.dothing();
????}
}
4.如果要按照上述的方法使用代理模式,那么真实角色必须是事先已经存在的,并将其作为代理对象的内部属性。但是实际使用时,
一个真实角色必须对应一个代理角色,如果大量使用会导致类的急剧膨胀;此外,如果事先并不知道真实角色,该如何使用代理呢?
这个问题可以通过Java的动态代理类来解决5.如果要按照上述的方法使用代理模式,那么真实角色必须是事先已经存在的,并将其作
为代理对象的内部属性。但是实际使用时,一个真实角色必须对应一个代理角色,如果大量使用会导致类的急剧膨胀;此外,如果事
先并不知道真实角色,该如何使用代理呢?这个问题可以通过Java的动态代理类来解决
package?dynamicproxy;
import?java.lang.reflect.InvocationHandler;
import?java.lang.reflect.Method;
public?class?DynamicSubject?implements?InvocationHandler?...{
????
public?DynamicSubject()?...{
????????
????????
????}
????
????public?DynamicSubject(Object?obj)?...{
????????
????????sub?=?obj;
????}
????
????private?Object?sub;
????public?Object?invoke(Object?proxy,?Method?method,?Object[]?args)
????????????throws?Throwable?...{
????????//?TODO?Auto-generated?method?stub
????????System.out.println("before?you?do?thing");
????????method.invoke(sub,?args);
????????System.out.println("after?you?do?thing");
????????return?null;
????}
}
该代理类的内部属性为Object类,实际使用时通过该类的构造函数DynamicSubject(Object obj)对其赋值;此外,
在该类还实现了invoke方法,该方法中的
method.invoke(sub,args);
其实就是调用被代理对象的将要被执行的方法,方法参数sub是实际的被代理对象,args为执行被代理对象相应操作所需的参数。
通过动态代理类,我们可以在调用之前或之后执行一些相关操作。
调用事例
package?dynamicproxy;
import?java.lang.reflect.InvocationHandler;
import?java.lang.reflect.Proxy;
import?proxypattern.RealSubject;
import?proxypattern.Subject;
public?class?Client?...{
????/**?*//**
?????*?@param?args
?????*/
????public?static?void?main(String[]?args)?throws?Throwable...{
????????//?TODO?Auto-generated?method?stub
?????????RealSubject?rs=new?RealSubject();
?????????InvocationHandler?ds=new?DynamicSubject(rs);
?????????Class?cls=rs.getClass();
?????????Subject?subject=(Subject)Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),ds);
?????????subject.dothing();
????}
}
通过这种方式,被代理的对象(RealSubject)可以在运行时动态改变,需要控制的接口(Subject接口)可以在运行时改变,
控制的方式(DynamicSubject类)也可以动态改变,从而实现了非常灵活的动态代理关系。