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

时间:2016-10-09 19:35:42

标签: java spring proxy guice

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

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

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

Guice的同样问题!

3 个答案:

答案 0 :(得分:1)

每次使用@Transactional@Cacheable等注释时,Spring都会使用代理。它的AOP与需要后编译或编织的复杂AOP无关。

无论如何,请注意,如果您的某个服务已经自动安装存储库,并且您在服务内创建了服务在您设置存储库的类中,这将自动用作代理(如果有需要它的注释)。

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

答案 1 :(得分:1)

在HK2中,是否为注射点制作代理取决于注射的豆的范围/背景。特别是在HK2中,范围可以用Proxiable注释。您可以使用Proxiable注释来控制是否应该生成代理以将bean注入到同一范围的其他bean中。

您可以进一步控制不可代理作用域中的bean是否被代理,或者代理作用域中的bean是否不应该使用注释UnproxiableUseProxy进行代理。 EDSL中也有等效的动词(例如ServiceBindingBuilder.proxyForSameScope)。

此外,如果AOP正在播放,HK2将生成代理

答案 2 :(得分:1)

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扩展。除了OlivierGrégoire在评论中提到的那些,我不知道更多的Guice用例。