Java 和注入防御副本

发布于 2024-12-09 17:37:50 字数 1761 浏览 0 评论 0原文

所以我开始真正喜欢防御副本的概念目的是使代码更加“安全”,但不幸的是,它们似乎与 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 的强迫症很满意!

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

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

So I'm starting to really like the concept of defensive copies for the purpose of making code more "secure", but unfortunately they seem to inherently conflict with the wonderful separation of concerns addressed by AOP.

By this, I mean that before I was introduced to AOP, I would manually validate the arguments to all my methods, like so:

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

    // ...
}

Now I use Apache Bean Validator to validate my methods, and any exception that gets thrown I handle via AOP. This cleans my code up nicely and separates my business logic (what I'm really interested in!) from the dull, boring validation checking, exception throwing, etc.

But now that I'm starting to like the concept of making defensive copies, I'm starting to right methods that all look the same again:

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

    // ...
}

So, my question:

Is there a de facto way of using AOP/IoC (any framework! - I'm desperate!) to write advice/pointcuts that will separate-out this dull, arduous (ha!) task of manually writing defensive copies and injecting them back into a local (method) object? That way, I could get the security benefits of defensive copies, with all the cleanliness of AOP/IoC.

I imagine that I would have to write advice that intercepts all methods and that uses dependency injection to somehow create pooled/managed instances of that methods parameters; these instances would be the defensive copies. Then, back in my target classes, I could use IoC to gain access to these defensive copies (beans).

Under this (general) paradigm, I imagine the code would then look like this:

@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");

    // ...
}

Now, oWidget is a defensive copy of p_oWidget, and I don't have to manually write it. Huge time savings, and my OCD with AOP is satisfied!

But I'm not even sure if AOP frameworks like AspectJ/AOP Alliance and IoC framework like Spring or Guice would even support such a concept.

I also have an enormous amount of respect for the SO community and would like some general input here - comment/recommendations/etc. Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

强者自强 2024-12-16 17:37:50

AspectJ 的 around 建议允许您在使用 ProceedingJoinPoint#proceed(Object[])

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

AspectJ's around advice lets you supply your own parameters to the intercepted method when using ProceedingJoinPoint#proceed(Object[]).

In the advice, you could check if a given parameter is copyable – in your case, using reflection to find a declared constructor that takes a single parameter of the type of the object, or however else you choose to mark objects that you want to make defensive copies of – and then proceed with the method using the copies instead of the original parameters.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文