当前位置: 首页 > 面试题库 >

Java方法缺少(ala Ruby)进行装饰?

陶成济
2023-03-14
问题内容

Java中是否有任何技术可以拦截消息(方法调用),例如Ruby中的method_missing技术?这将使编码修饰符和代理非常容易,就像在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())


问题答案:

正如其他人已经正确说过的那样,请使用DynamicProxy。这是一个例子。

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

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

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

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();
     }
}


 类似资料:
  • 问题内容: 我在项目中使用Spring 5。直到今天,仍然有可用的方法。 但是下载最新的快照后,它突然消失了!有没有参考说明该方法现在不可用? 我的依赖项列表: 更新: 似乎此方法已被替换为 问题答案: 请参阅与该提交关联的DATACMNS-944,它具有以下重命名

  • 我在我的项目中使用Spring 5。直到今天,还有可用的方法。 但下载最新快照后,它突然消失了!有没有参考现在没有的方法? 我的依赖项列表: 更新: 似乎此方法已被

  • 我是groovy的新手。我有这样的代码。 串味 从这个客户端映射中,我需要迭代appName和enable的值。为此,我使用了get方法。。。我对此不确定。 使用此get方法时,我遇到以下错误。因为我是groovy新手,所以我不知道这里发生了什么 棒极了。lang.MissingMethodException:没有方法com的签名。康卡斯特。csv。哈克索。SecureFirebaseRestCl

  • 我有个问题。我想使用XSSF工作簿读取xlsx中的工作表名称。我在我的项目中添加了外部jar:poi-3.9-jar poi-ooxml-3.11.jar xmlbeans-2.4.0.jar 但它总是抛出这样一个例外: java.lang.NoClassDefFoundError:org/apache/poi/UnsupportedFileFormatException 有人知道我忘了什么吗?谢

  • 问:您是如何处理这些用例的? 是否使用静态帮助器方法? 是否使用后跟isafter/isbefore的详细等于? 是否使用否定的相反条件? 是否使用第三方库帮助程序? null Edit:正如Andreas所建议的,我用方法添加了版本,我希望我正确(无需测试)。 编辑2:示例:

  • 我是Groovy新手,但我正在尝试编写一个简单的递归方法来将层次路径解析为对象图。以下是我尝试过的: 但我得到以下错误: 我错过了什么?