1

有什么可以达到以下等效的:

<import resource="a.xml">
    <prop name="key" value="a"/>
</import>

<import resource="a.xml">
    <prop name="key" value="b"/>
</import>

这样在资源 a 中定义的 bean 会看到具有两个不同值的属性键吗?目的是这将用于命名导入中的 bean,以便出现资源 a.xml:

<bean id="${key}"/>

因此,应用程序将有两个命名的 bean ab现在可以使用相同的定义但作为不同的实例。我知道原型范围;不是出于这个原因,将创建许多具有实际上不是原型的相互依赖关系的对象。目前我只是复制 a.xml,创建 b.xml 并使用等效的sed命令重命名所有 bean。我觉得必须有更好的方法。

4

1 回答 1

1

我想 PropertyPlaceholderConfigurers 在每个容器的基础上工作,所以你不能通过 xml 导入来实现这一点。

回覆The application would have two beans named a and b now available with the same definition but as distinct instances

我认为您应该考虑使用当前应用程序上下文作为父应用程序上下文手动创建其他应用程序上下文(例如 ClassPathXmlApplicationContext)。因此,您的many objects created with interdependencies集合将分别驻留在自己的容器中。

但是,在这种情况下,您将无法b从 -container 引用 -beans a

更新您可以通过注册BeanDefinitionRegistryPostProcessor专用 bean手动后处理 bean 定义(添加新定义) ,但这个解决方案似乎也并不容易。

好的,这是我手动导入 xml 文件的粗略尝试:

免责声明:我实际上是非常糟糕的 java io 程序员,所以请仔细检查资源相关代码:-)

public class CustomXmlImporter implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanFactory(
            ConfigurableListableBeanFactory beanFactory) throws BeansException {
    }

    private Map<String, String> properties;

    public void setProperties(Map<String, String> properties) {
        this.properties = properties;
    }

    public Map<String, String> getProperties() {
        return properties;
    }

    private void readXml(XmlBeanDefinitionReader reader) {
        InputStream inputStream;
        try {
            inputStream = new ClassPathResource(this.classpathXmlLocation).getInputStream();
        } catch (IOException e1) {
            throw new AssertionError();
        }
        try {

            Scanner sc = new Scanner(inputStream);
            try {
                sc.useDelimiter("\\A");
                if (!sc.hasNext())
                    throw new AssertionError();
                String entireXml = sc.next();

                PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${",
                        "}", null, false);
                Properties props = new Properties();
                props.putAll(this.properties);
                String newXml = helper.replacePlaceholders(entireXml, props);
                reader.loadBeanDefinitions(new ByteArrayResource(newXml.getBytes()));

            } finally {
                sc.close();
            }

        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                throw new AssertionError();
            }
        }
    }

    private String classpathXmlLocation;

    public void setClassPathXmlLocation(String classpathXmlLocation) {
        this.classpathXmlLocation = classpathXmlLocation;
    }

    public String getClassPathXmlLocation() {
        return this.classpathXmlLocation;
    }

    @Override
    public void postProcessBeanDefinitionRegistry(
            BeanDefinitionRegistry registry) throws BeansException {
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(registry);
        readXml(reader);
    }
}

XML配置:

<bean class="CustomXmlImporter">
    <property name="classPathXmlLocation" value="a.xml" />
    <property name="properties">
        <map>
            <entry key="key" value="a" />
        </map>
    </property>
</bean>
<bean class="CustomXmlImporter">
    <property name="classPathXmlLocation" value="a.xml" />
    <property name="properties">
        <map>
            <entry key="key" value="b" />
        </map>
    </property>
</bean>

此代码从类路径加载资源。在做这样的事情之前我会三思而后行,无论如何,你可以以此为起点。

于 2012-11-22T13:57:43.337 回答