我试图从占位符中获取一些值到自定义架构属性(cfg:merge-elements' target),但它不起作用:
somexml.xml:
<bean id="stateMachineNamingStrategy" class="com.mycompany.statemachine.hibernate.StateMachineNamingStrategy">
<property name="prefix" value="${statemachine.table_prefix}"/>
</bean>
<cfg:merge-elements id="packages-com.mycompany.statemachine" target="${session-factory-pkgs}">
<value>com.mycompany.statemachine.machine.impl</value>
</cfg:merge-elements>
这些定义在同一个xml中。第一个(stateMachineNamingStrategy)正确地从$ {statemachine.table_prefix}获取值。
第二个无法在 $ {session-factory-pkgs} 中检索它。例外情况表明属性值尚未转换:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named '${session-factory-pkgs}' is defined
为什么不将占位符转换为其值?
答案 0 :(得分:0)
如果有人遇到同样的问题:
事实证明,在我的NamespaceHandler
中,我注册了一个扩展BeanDefinitionRegistryPostProcessor
的新BeanDefinition。这些特殊的后处理器在正常BeanFactoryPostProcessor
之前执行,以允许注册或删除BeanDefinitions。因此,没有办法让PropertyPlaceholderConfigurer(这是一个普通的BeanPostProcessor)在BeanDefinitionRegistryPostProcessor之前执行。
你可以在XmlWebApplicationContext(AbstractApplicationContext).invokeBeanFactoryPostProcessors中看到它:
Map<String, BeanDefinitionRegistryPostProcessor> beanMap =
beanFactory.getBeansOfType(BeanDefinitionRegistryPostProcessor.class, true, false);
List<BeanDefinitionRegistryPostProcessor> registryPostProcessorBeans =
new ArrayList<BeanDefinitionRegistryPostProcessor>(beanMap.values());
OrderComparator.sort(registryPostProcessorBeans);
for (BeanDefinitionRegistryPostProcessor postProcessor : registryPostProcessorBeans) {
//!!!!! BeanDefinitionRegistryPostProcessors are excecuted!!!!!
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(registryPostProcessorBeans, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
processedBeans.addAll(beanMap.keySet());
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {