Java 依赖注入与AOP有点类似吗?

Java 依赖注入与AOP有点类似吗?,java,dependency-injection,proxy,spring-aop,Java,Dependency Injection,Proxy,Spring Aop,与工作中的同事进行了讨论:当代理对象在@AOP中发挥作用时,我们对AOP是否与DI有点类似感到困惑,并阅读(下文)Spring DI也使用动态代理来创建对象 所有依赖注入框架现在都带有一些类似AOP的特性 功能:当您需要实现一个接口时,您可以 不要接收实现本身,而是接收代理 (称为DynamicProxy),此代理在 调用最终实现看起来像AOP,闻起来像 AOP,但它很难与成熟的AOP框架相比 我想说的是,使用依赖注入使基于动态代理的AOP更易于使用,因此是一条自然的路径 但是您可以使用依赖项

与工作中的同事进行了讨论:当代理对象在@AOP中发挥作用时,我们对AOP是否与DI有点类似感到困惑,并阅读(下文)Spring DI也使用动态代理来创建对象

所有依赖注入框架现在都带有一些类似AOP的特性 功能:当您需要实现一个接口时,您可以 不要接收实现本身,而是接收代理 (称为DynamicProxy),此代理在 调用最终实现<代码>看起来像AOP,闻起来像 AOP,但它很难与成熟的AOP框架相比


我想说的是,使用依赖注入使基于动态代理的AOP更易于使用,因此是一条自然的路径


但是您可以使用依赖项注入而不使用AOP,也可以使用AOP而不使用依赖项注入。顺便说一句,代理不仅用于实现AOP,还用于解决循环依赖关系,或者能够将较小范围的对象(例如,请求范围的对象)注入较大范围的对象(例如,单例范围的对象)。

我想说,使用依赖项注入可以使基于动态代理的AOP更易于使用,这是一条自然的道路

但是您可以使用依赖项注入而不使用AOP,也可以使用AOP而不使用依赖项注入。顺便说一句,代理不仅用于实现AOP,还用于解决循环依赖关系,或者能够将较小范围的对象(例如,请求范围的对象)注入较大范围的对象(例如,单例范围的对象)。

  • 依赖注入是将组件注入到需要其行为的组件中
  • 面向方面编程是关于将横切关注点应用于代码(实际上是关于遵守规则)
当使用DI时,AOP将变得更加自然。您可以使用代理来实现这一点,但我个人的偏好是通过应用好的旧代理来实现这一点

它看起来像AOP,闻起来像AOP,但很难与a相比 成熟的AOP框架

我完全不同意这份声明的作者。根据我的经验,像PostSharp这样的工具允许您解决应用程序中的设计缺陷。这使得这些工具在处理遗留应用程序或无法更改的设计(例如处理
INotityPropertyChanged
接口)时非常强大。然而,尽管这些工具允许您在不修复设计的情况下添加AOP特性,但这些设计缺陷在项目的生命周期中仍然会困扰您

一个简单的例子是可测试性。像这样的工具不能解决应用程序的可测试性问题,而依赖注入模式正是解决了这一问题。由于这些工具在编译时编织在方面中,因此很难在没有方面的情况下测试代码(这是进行单元测试时需要做的,有时甚至是集成测试时)。您必须对编译器指令进行巧妙的处理,但这只能解决部分问题,因为您仍然希望测试这些方面,但只是在隔离状态下,就像您希望在隔离状态下测试每一段代码一样(这就是单元测试的意义所在)。即使你能解决它,你的代码仍然很难维护。无法维护的代码是由设计缺陷造成的

文章作者说:

第一个问题是动态代理只允许添加方面 服务的显式边界,即您选择公开的边界 作为一个接口。不能向私有或静态方法添加方面, 即使你想

他在这一点上是完全正确的,但是如果您想向私有或静态方法添加方面,那么您的设计就有问题:修复设计

第二个问题更具戏剧性。当你沉迷于一些 AOP的好处是,您可以开始使用动态代理,即使您 不需要依赖注入,改变您的 代码只是因为动态代理的要求。这是 错。AOP不要求您更改应用程序的体系结构 代码

作者也是对的:在使用PostSharp时,不需要修改AOP的体系结构。但如果设计不正确,即使使用PostSharp这样的工具,应用方面仍然困难得多。不要忘记,PostSharp的无属性AOP只有在使用商业版本时才可能实现。使用属性应用AOP仍然会导致高耦合和维护问题。所有DI工具(至少对于.NET)都可以自由使用,默认情况下无属性使用

对于好的设计来说,根本没有其他选择,在大多数情况下,拥有正确的设计工具(如PostSharp)会变得多余。在某些边缘情况下,它们仍然是有益的(并且在这些情况下可能非常有益),但根据我的经验,当您的设计被修改时,这些情况是罕见的

现在问题显然变成了:什么是好的实体设计?没有现成的、始终有效的设计可以应用于所有应用程序。我设计的每个应用程序都是不同的,尽管在过去几年中,我看到了某些重复出现的模式,这可能对您也有好处。我以前写过这方面的文章,而且。这些文章中描述的模式已经成为我帮助设计和构建的许多应用程序的基本构建块。这些图案的关键成分是固体。

  • 依赖注入是将组件注入到需要其行为的组件中
  • 面向方面编程是关于将横切关注点应用于代码(实际上是关于遵守规则)
当使用DI时,AOP将出现