【问题标题】:Java and Injecting Defensive CopiesJava 和注入防御性副本
【发布时间】:2014-06-18 22:44:11
【问题描述】:

所以我开始非常喜欢 defensive copies 的概念,目的是让代码更“安全”,但不幸的是,它们似乎与AOP。

我的意思是,在我被介绍给 AOP 之前,我会手动验证所有方法的参数,如下所示:

public void doSomething(final int p_iAge, final Widget p_oWidget)
        throws IllegalArgumentException
{
    if(p_oWidget == null)
        throw new IllegalArgumentException();

    // ...
}

现在我使用 Apache Bean Validator 来验证我的方法,并通过 AOP 处理任何抛出的异常。这很好地清理了我的代码,并将我的业务逻辑(我真正感兴趣的!)与枯燥乏味的验证检查、异常抛出等区分开来。

但现在我开始喜欢制作防御性副本的概念,我开始纠正看起来都一样的方法:

@NotNull(message="Widget cannot be null.")
public void doSomething(final int p_iAge, final Widget p_oWidget)
{
    Widget oWidget = new Widget(p_oWidget);

    // ...
}

所以,我的问题:

有没有一种使用 AOP/IoC(任何框架!-我很绝望!)的事实上的方法来编写建议/切入点,将手动编写这个枯燥、艰巨(哈!)的任务分开防御性副本并将它们注入到本地(方法)对象中?这样,我可以获得防御性副本的安全优势,以及 AOP/IoC 的所有清洁度。

我想我必须编写拦截所有方法并使用依赖注入以某种方式创建该方法参数的池/托管实例的建议;这些实例将是防御副本。然后,回到我的目标类,我可以使用 IoC 来访问这些防御性副本(bean)。

在这个(一般)范式下,我想代码将如下所示:

@NotNull(message="Widget cannot be null.")
public void doSomething(final int p_iAge, final Widget p_oWidget)
{
    // By the time we get here, bean validation has already made sure
    // that p_oWidget isn't null, and the AOP method interceptor has already
    // executed and created the "defensive-widget" bean.
    Widget oWidget = springOrWhateverInjector.getBean("defensive-widget");

    // ...
}

现在oWidgetp_oWidget 的防御性副本,我不必手动编写它。节省大量时间,我的 AOP 强迫症很满意!

但我什至不确定 AOP 框架(如 AspectJ/AOP Alliance)和 IoC 框架(如 Spring 或 Guice)是否支持这样的概念。

我也非常尊重 SO 社区,并希望在此提供一些一般性意见 - 评论/建议/等。提前致谢!

【问题讨论】:

  • 我不是 AOP 方面的专家,但您不能创建一个动态代理/拦截器来拦截您的方法调用并装饰/包装/“防御性复制”您的 Widget 对象,然后传递装饰的 Widget进入你的方法(假设你的 Widget 类是一个接口)?
  • 输出防御副本在非常有限的情况下很有用。更好的方法是非可变对象(可能涉及构造时的防御性复制)和写时复制。
  • 呃,匈牙利符号的变态。在任何情况下,您都可以访问输入伙伴和输出值,您可以根据需要对它们进行优化。
  • 参数,不是合作伙伴。或者长尾小鹦鹉,另一个顶级自动完成选项:(

标签: java validation dependency-injection aop


【解决方案1】:

AspectJ 的 around 建议允许您在使用 ProceedingJoinPoint#proceed(Object[]) 时将自己的参数提供给被拦截的方法。

在建议中,您可以检查给定参数是否可复制 - 在您的情况下,使用反射来查找声明的构造函数,该构造函数采用对象类型的单个参数,或者其他您选择标记要制作防御性副本的对象,然后使用副本而不是原始参数继续执行该方法。

【讨论】:

    猜你喜欢
    • 2011-01-15
    • 1970-01-01
    • 2013-10-12
    • 2019-04-09
    • 2011-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多