Spring 和 Guice:DI 框架何时创建代理?

Spring and Guice: when DI frameworks create proxies?

我们知道 Spring 和 Guice 等 DI 框架有时会创建代理而不是 beans。要在 equals 和 hashcode 方法中比较这些代理,我们应该使用 instanceOf 运算符,因为它们的 class 不再与原始代理相同。 此外(可能)这些代理可能会在一些未初始化的状态下创建,就像 Hibernate 代理一样(这只是我的猜测)。

我只知道 Spring 创建 bean 代理的一种情况:当您使用 @Configuration 注释它时。 还有其他类似情况吗? Spring 是否创建未初始化的代理,这些代理仅在访问字段后才初始化它们的字段?

我发现了一个类似的问题:When does Spring creates proxies in the bean's lifecycle?,但请注意它与 AOP 使用案例有关。我问的是不涉及 AOP 的简单 DI 用法。

Guice 同样的问题!

每次使用 @Transactional@Cacheable 等注释时,

Spring 都会使用代理。它的 AOP 与需要 post 编译或编织的复杂 AOP 无关。

无论如何,请注意,如果在您的 服务 中,您已经自动连接了 存储库 ,并且在 service 你在设置 存储库 的地方创建一个 class,这将自动用作代理(如果有注释需要它)。

关于Guice,答案在@Oliver的评论里。

在 HK2 中是否为注入点制作代理取决于被注入的 bean scope/context。特别是,在 HK2 中,可以使用 Proxiable. You can control with the Proxiable 注释来注释范围是否应生成代理以将 bean 注入同一范围的其他 bean。

您可以进一步控制是否在不可代理范围内的 beans 被代理或在可代理范围内的 beans 不应该使用注释 Unproxiable and UseProxy. There are equivalent verbs in the EDSL as well (for example ServiceBindingBuilder.proxyForSameScope).

此外,如果使用 AOP,HK2 将生成代理

Guice 中的辅助注入可能是您感兴趣的用例。长话短说。

工厂接口:

public interface PaymentFactory {
  public Payment create(Date startDate, Money amount);
}

支付实施:

public class RealPayment implements Payment {
  @Inject
  public RealPayment(
        CreditService creditService,
        AuthService authService,
        @Assisted Date startDate,
        @Assisted Money amount);
  }
  ...
}

绑定:

install(new FactoryModuleBuilder()
     .implement(Payment.class, RealPayment.class)
     .build(PaymentFactory.class));

Guice 随后将为您生成 PaymentFactory 实现。

wiki 中提供了更多详细信息和完整示例。注意:这是一个 guice 扩展。除了 Olivier Grégoire 在他的评论中提到的那些,我不知道还有更多的 Guice 用例。