你的回答很棒。我也想分享一些关于另一种解决方案的笔记,该解决方案允许原型成员通过使用内部bean在Spring IoC容器生命周期中进行本地管理。
最近我为一个关于内部bean的单独问题写了一个
回答。内部bean是通过将bean属性值分配为
BeanDefinition
对象来创建的。 Bean定义属性值会自动解析为它们定义的bean的
(inner)
实例(作为托管单例bean)。
以下XML上下文配置元素可用于为每个引用创建不同的可自动装配的
ForkJoinPool
bean,这些bean将被管理(在上下文关闭时将调用
@PreDestroy
)。
<!
<bean id="forkJoinPool" class="org.springframework.beans.factory.support.GenericBeanDefinition" scope="prototype">
<property name="beanClass" value="org.springframework.scheduling.concurrent.ForkJoinPoolFactoryBean" />
</bean>
这种行为取决于将引用分配为bean定义的属性值。这意味着默认情况下,
@Autowired
和构造函数注入无法使用此方法,因为这些自动装配方法会立即解析该值,而不是使用
AbstractAutowireCapableBeanFactory#applyPropertyValues
中的属性值解析。按类型自动装配也不起作用,因为类型解析不会通过
BeanDefinition
找到生成的类型。
只有两个条件之一成立才能使用此方法:
- 依赖的bean也在XML中定义。
- 或者,如果自动装配模式设置为
AutowireCapableBeanFactory#AUTOWIRE_BY_NAME
。
<!-- Setting bean references through XML -->
<beans ...>
<bean id="myOtherBean" class="com.example.demo.ForkJoinPoolContainer">
<property name="forkJoinPool" ref="forkJoinPool" />
</bean>
</beans>
<!-- Or setting the default autowire mode -->
<beans default-autowire="byName" ...>
...
</beans>
Two additional changes could likely be made to enable constructor-injection and @Autowired
-injection.
Constructor-injection:
The bean factory assigns an AutowireCandidateResolver
for constructor injection. The default value (ContextAnnotationAutowireCandidateResolver
) could be overridden (DefaultListableBeanFactory#setAutowireCandidateResolver
) to apply a candidate resolver which seeks eligible beans of type BeanDefinition
for injection.
@Autowired
-injection:
The AutowiredAnnotationBeanPostProcessor
bean post processor directly sets bean values without resolving BeanDefinition
inner beans. This post processor could be overridden, or a separate bean post processor could be created to process a custom annotation for managed prototype beans (e.g., @AutowiredManagedPrototype
).