我们知道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的同样问题!
答案 0 :(得分:1)
每次使用@Transactional
或@Cacheable
等注释时,Spring都会使用代理。它的AOP与需要后编译或编织的复杂AOP无关。
无论如何,请注意,如果您的某个服务已经自动安装存储库,并且您在服务内创建了服务在您设置存储库的类中,这将自动用作代理(如果有需要它的注释)。
关于Guice,答案在@Oliver的评论中。
答案 1 :(得分:1)
在HK2中,是否为注射点制作代理取决于注射的豆的范围/背景。特别是在HK2中,范围可以用Proxiable注释。您可以使用Proxiable注释来控制是否应该生成代理以将bean注入到同一范围的其他bean中。
您可以进一步控制不可代理作用域中的bean是否被代理,或者代理作用域中的bean是否不应该使用注释Unproxiable和UseProxy进行代理。 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用例。