免责声明:
我已经阅读了有关JDK动态代理和CGLIB的专心研究人员:https://stackoverflow.com/a/21762454/2674303我已阅读以下有趣的文章:Injecting Spring Prototype bean into Singleton bean
Prototype:
@Service @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) class MessageBuilder { private static final AtomicInteger instanceCounter = new AtomicInteger(0); MessageBuilder() { instanceCounter.incrementAndGet(); } static int getInstanceCounter() { return instanceCounter.get(); } .... }
Singleton:
@Service class MessageService { private final MessageBuilder messageBuilder; MessageService(MessageBuilder messageBuilder) { this.messageBuilder = messageBuilder; } Message createMessage(String content, String receiver) { return messageBuilder .withContent(content) .withReceiver(receiver) .build(); } }
测试:
@RunWith(SpringRunner.class) @SpringBootTest public class MessageServiceTest { @Autowired private MessageService messageService; @Test public void shouldCreateTwoBuilders() throws Exception { //when messageService.createMessage("text", "alice"); messageService.createMessage("msg", "bob"); //then int prototypeCounter = MessageBuilder.getInstanceCounter(); assertEquals("Wrong number of instances", 2, prototypeCounter); } }
显然测试失败,因为注入仅发生一次,实际结果将为1,但我们预期为2。
第二种情况:
Singleton和Test相同,但是原型现在看起来像这样(proxyMode已更改):
,因为在内部@Service @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS) class MessageBuilder { // ... }
当我们开始测试时,我们看到实际结果是6
createMessage
方法中,messageBuilder被访问了3次。并且createMessage
方法被调用两次,因此3 * 2 = 6。为了解释行为作者提供了下图:
我无法理解哪个bean是依赖的,为什么每次访问代理messageBuilder
都会使新bean实例化。为什么对于第一种情况,情况有所不同?你能解释一下吗?据我了解-代理无论如何都可以创建-使用CGLIB或使用动态代理,以便无论如何都可以注入代理]
免责声明:我已经阅读了有关JDK动态代理和CGLIB的专心研究人员:https://stackoverflow.com/a/21762454/2674303我已经阅读了以下有趣的文章:注入Spring原型bean ...
如果您定义一个具有prototype
范围的bean,当从Spring上下文中引用该bean时,ApplicationContext
将返回一个新实例。在您的第一个示例中,当创建MessageBuilder
singleton
MessageService
prototype