【发布时间】:2011-02-27 10:17:10
【问题描述】:
我正在尝试使用 Spring 上下文命名空间在应用程序中构建一些现有的配置对象。我已经定义了一个上下文,如果工作令人满意的话,我几乎已经有了 - 但是,我希望我的命名空间定义的一个 bean 隐式引用另一个:
考虑名为“节点”的类:
public Class Node {
private String aField;
private Node nextNode;
public Node(String aField, Node nextNode) {
...
}
现在在我的 Spring 上下文中,我有这样的东西:
<myns:container>
<myns:node aField="nodeOne"/>
<myns:node aField="nodeTwo"/>
</myns:container>
现在我希望 nodeOne.getNextNode() == nodeTwo 成为 true。这样nodeOne.getNextNode() 和nodeTwo 指的是同一个bean 实例。这些几乎就是我在AbstractBeanDefinitionParser 中的相关部分:
public AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
...
BeanDefinitionBuilder containerFactory = BeanDefinitionBuilder.rootBeanDefinition(ContainerFactoryBean.class);
List<BeanDefinition> containerNodes = Lists.newArrayList();
String previousNodeBeanName;
// iterate backwards over the 'node' elements
for (int i = nodeElements.size() - 1; i >= 0; --i) {
BeanDefinitionBuilder node = BeanDefinitionBuilder.rootBeanDefinition(Node.class);
node.setScope(BeanDefinition.SCOPE_SINGLETON);
String nodeField = nodeElements.getAttribute("aField");
node.addConstructorArgValue(nodeField);
if (previousNodeBeanName != null) {
node.addConstructorArgValue(new RuntimeBeanReference(previousNodeBeanName));
} else {
node.addConstructorArgValue(null);
}
BeanDefinition nodeDefinition = node.getBeanDefinition();
previousNodeBeanName = "inner-node-" + nodeField;
parserContext.getRegistry().registerBeanDefinition(previousNodeBeanName, nodeDefinition);
containerNodes.add(node);
}
containerFactory.addPropertyValue("nodes", containerNodes);
}
创建应用程序上下文时,我的 Node 实例被创建并被识别为单例。此外,nextNode 属性填充了具有先前节点配置的 Node 实例 - 但是,它不是相同的实例。
如果我在 Node 的构造函数中输出一条日志消息,我会看到为每个节点 bean 定义创建了两个实例。
我自己可以想到一些解决方法,但我热衷于使用现有模型。那么谁能告诉我如何传递这些运行时 bean 引用,以便为我的 Node 实例获得正确的单例行为?
【问题讨论】:
标签: java spring namespaces