我修改了你的
MessageDigestFactoryBean
类,以便输出
algorithmName
同样,这将有助于澄清此案。更改后,输出为:
<> MessageDigestFactoryBean.postConstructHandler() SHA1
<> MessageDigestFactoryBean.postConstructHandler() MD5
<> MessageDigestFactoryBean.isSingleton() SHA1
<> MessageDigestFactoryBean.getObject() SHA1
<> MessageDigestFactoryBean.isSingleton() MD5
<> MessageDigestFactoryBean.getObject() MD5
<> MessageDigestFactoryBean.isSingleton() SHA1
<> MessageDigestFactoryBean.getObjectType() SHA1
<> MessageDigestFactoryBean.isSingleton() MD5
<> MessageDigestFactoryBean.getObjectType() MD5
让我们试着分析一下这个输出。
-
你已经申报了两个
消息挖掘FactoryBean
实例,因此当Spring在上下文中发现它们时,它会初始化它们,并在过程中调用带注释的方法
@PostConstruct
-
MessageDigestFactoryBean.postConstructHandler()
.
-
然后,正如Spring发现的那样
digester
bean,它试图获得它的依赖项。Spring认为依赖关系是
FactoryBean
,所以它最终调用
FactoryBeanRegistrySupport.getObjectFromFactoryBean
。此方法首先检查bean是否为singleton,调用
MessageDigestFactoryBean.isSingleton()
如果bean是singleton,那么它首先尝试从工厂bean对象缓存中获取对它的引用。由于这是第一次引用这个bean,它还没有被缓存,所以引用是通过
MessageDigestFactoryBean.getObject()
,已缓存,然后返回。由于您在中引用了两个工厂bean
蒸煮器
,显然,对每一个都重复这个过程。
-
初始化完成后,Spring尝试发布
ContextRefreshedEvent
到生命周期处理器,因此它在所有bean定义中搜索实现的实例
Lifecycle
界面基本上,Spring循环遍历上下文中定义的所有bean,检查匹配类型的singleton bean(实际上还有更多的检查,但我们只对这些感兴趣)。在这个过程中,对于工厂的豆子
消息挖掘FactoryBean.isSingleton()
被调用以确定对象是否为singleton,并且
MessageDigestFactoryBean.getObjectType()
被调用以检查对象的类型是否可从
Lifecycle
界面同样,由于您有两个
消息挖掘FactoryBean
,这些方法中的每一个都被调用两次。
这就是你打电话时会发生的事情
ctx.refresh()
。这只是一个夸张的外观,显然Spring在引擎盖下做了很多工作,但这就是我所能看到的与您的输出相关的全部内容。希望这能回答你的第一个问题。
现在,对于第二个问题——不,您没有做错任何事情,您看到的输出只是反映了Spring的内部功能。