缺少Java方法(ala Ruby)进行装饰? [英] Java method missing (ala Ruby) for decorating?

查看:86
本文介绍了缺少Java方法(ala Ruby)进行装饰?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Java中是否有任何可用于拦截消息(方法调用)的技术,如Ruby中的method_missing技术?这将允许编码装饰器和代理非常容易
,如Ruby:

Is there any technique available in Java for intercepting messages (method calls) like the method_missing technique in Ruby? This would allow coding decorators and proxies very easily, like in Ruby:

:Client            p:Proxy                    im:Implementation
-------           ----------                  -----------------

p.foo() -------> method_missing()
                    do_something
                    im.foo() ------------------> do_foo


p.bar() --------> method_missing()
                   do_something_more
                    im.bar() -------------------> do_bar

(注意:代理只有一种方法:method_missing())

(Note: Proxy only has one method: method_missing())

推荐答案

正如其他人已经正确说过的那样,使用DynamicProxy。下面是一个示例。

As others have correctly said already, use a DynamicProxy. Here's an example.

此类使用DynamicProxy拦截HammerListener接口中声明的方法的调用。它执行一些日志记录,然后委托给真正的HammerListener实现(是的,可以用AOP完成同样的事情)。

This class uses a DynamicProxy to intercept invocations of methods declared in the "HammerListener" interface. It does some logging and then delegates to the "real" HammerListener implementation (yes, the same thing can be done with AOP).

请参阅newInstance方法进行代理实例化(请注意,您需要传入代理应实现的接口 - 代理可以实现多个接口。)

See the newInstance method for proxy instantiation (note that you need to pass in the interface(s) the proxy should implement - a proxy can implement multiple interface).

代理实现的接口上的所有方法调用都将最终作为对invoke方法的调用,该方法在InvocationHandler接口中声明。所有代理处理程序都必须实现此接口。

All method invocations on interfaces that the proxy implements will end up as calls to the "invoke" method, which is declared in the "InvocationHandler" interface. All proxy handlers must implement this interface.

import java.lang.reflect.*;

/**
 * Decorates a HammerListener instance, adding BEFORE/AFTER 
 * log messages around all methods exposed in the HammerListener interface.
 */

public class HammerListenerDecorator implements InvocationHandler {

    private final HammerListener delegate;

    static HammerListener newInstance(HammerListener delegate) {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        return (HammerListener)Proxy.newProxyInstance(cl, new Class[]{HammerListener.class},
            new HammerListenerDecorator(delegate));
    }

    private HammerListenerDecorator(HammerListener delegate) {
        this.delegate = delegate;
     }

     @Override
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
         logger.info("BEFORE " + method.getName() + " {{{" + argsToString(args) + "}}}");
         Object rtn = method.invoke(delegate, args);
         logger.info("AFTER " + method.getName());
         return rtn;
     }

     private String argsToString(Object[] args) {
         StringBuilder sb = new StringBuilder();
         for (Object o : args) {
             sb.append(String.valueOf(o)).append(" ");
         }
         return sb.toString();
     }
}

这篇关于缺少Java方法(ala Ruby)进行装饰?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆