java中的动态代理

假设有如下接口和类的定义:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public interface Action {
void execute(Object target);
}
public abstract class BaseAction implements Action {
@Override
public abstract void execute(Object target);
}
public class RunAction extends BaseAction implements Action {
@Override
public void execute(Object target) {
System.out.println(target+":run");
}
}
public class WalkAction extends BaseAction implements Action {
@Override
public void execute(Object target) {
System.out.println(target+":walk");
}
}
public interface Action { void execute(Object target); } public abstract class BaseAction implements Action { @Override public abstract void execute(Object target); } public class RunAction extends BaseAction implements Action { @Override public void execute(Object target) { System.out.println(target+":run"); } } public class WalkAction extends BaseAction implements Action { @Override public void execute(Object target) { System.out.println(target+":walk"); } }
public interface Action {
    void execute(Object target);
}

public abstract class BaseAction implements Action {

    @Override
    public abstract void execute(Object target);
}

public class RunAction extends BaseAction implements Action {

    @Override
    public void execute(Object target) {
        System.out.println(target+":run");
    }
}

public class WalkAction extends BaseAction implements Action {

    @Override
    public void execute(Object target) {
        System.out.println(target+":walk");
    }
}

下面是使用jdk的动态代理类:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public class ActionProxy implements InvocationHandler {
private Action target;
public void bind(Action target)
{
this.target=target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
method.invoke(target,args);
return null;
}
}
public class ActionProxy implements InvocationHandler { private Action target; public void bind(Action target) { this.target=target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { method.invoke(target,args); return null; } }
public class ActionProxy implements InvocationHandler {

    private Action target;

    public void bind(Action target)
    {
        this.target=target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        method.invoke(target,args);
        return null;
    }
}

调用动态代理的代码片断:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
RunAction runAction=new RunAction();
ActionProxy actionProxy=new ActionProxy();
actionProxy.bind(runAction);
Action action=(Action)Proxy.newProxyInstance( actionProxy.getClass().getClassLoader(),runAction.getClass().getInterfaces() , actionProxy );
action.execute("Max Woods");
RunAction runAction=new RunAction(); ActionProxy actionProxy=new ActionProxy(); actionProxy.bind(runAction); Action action=(Action)Proxy.newProxyInstance( actionProxy.getClass().getClassLoader(),runAction.getClass().getInterfaces() , actionProxy ); action.execute("Max Woods");
RunAction runAction=new RunAction();
ActionProxy actionProxy=new ActionProxy();
actionProxy.bind(runAction);
Action action=(Action)Proxy.newProxyInstance( actionProxy.getClass().getClassLoader(),runAction.getClass().getInterfaces() , actionProxy );
action.execute("Max Woods");

Java中使用JDK实现动态代理类,需要实现InvocationHandler接口,如上面的ActionProxy,该接口的定义为:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
public interface InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; }
public interface InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;
}

而委托类则需要实现同一接口,如上面的RunAction和WalkAction都实现了Action接口,并且共同继承了BaseAction这个抽象基类,注意尽管BaseAction的抽象方法execute实现了Action接口,但在RunAction和WalkAction还是要显示声明实现了Action接口,否则在创建动态代理对象时会抛出类型转换异常。

如果使用cglib来实现代理,则要简单许多,也不需要被委托对象实现接口,下面是cglib实现的代理类,需要实现MethodInterceptor接口:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public class ActionInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("代理执行方法:"+method.getName());
return methodProxy.invokeSuper(o, objects);
}
}
public class ActionInterceptor implements MethodInterceptor { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("代理执行方法:"+method.getName()); return methodProxy.invokeSuper(o, objects); } }
public class ActionInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("代理执行方法:"+method.getName());
        return methodProxy.invokeSuper(o, objects);
    }
}

通过cglib代理调用,则更加简单:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Action action=(Action)Enhancer.create(WalkAction.class,new ActionInterceptor());
action.execute("Max Woods");
Action action=(Action)Enhancer.create(WalkAction.class,new ActionInterceptor()); action.execute("Max Woods");
Action action=(Action)Enhancer.create(WalkAction.class,new ActionInterceptor());
action.execute("Max Woods");
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享