小编典典

如何在Spring XML上下文中实现条件资源导入?

spring

我想实现的功能是“动态”(即基于配置文件中定义的属性)启用/禁用子Spring XML上下文的导入的能力。

我想像这样:

<import condition="some.property.name" resource="some-context.xml"/>

解析属性的位置(为布尔值),如果为true,则导入上下文,否则不导入。

到目前为止,我的一些研究:

  • 编写自定义NamespaceHandler(和相关类),以便我可以在自己的名称空间中注册自己的自定义元素。例如:<myns:import condition="some.property.name" resource="some-context.xml"/>

这种方法的问题在于,我不想复制Spring的整个资源导入逻辑,而且对我来说,执行此操作需要委派什么并不明显。

  • 重写DefaultBeanDefinitionDocumentReader以扩展“ import”元素的解析和解释的行为(在importBeanDefinitionResource方法中发生)。但是我不确定在哪里可以注册此扩展名。

阅读 647

收藏
2020-04-13

共2个答案

小编典典

现在,使用Spring 4完全可以做到这一点。

在你的主应用程序内容文件中

<bean class="com.example.MyConditionalConfiguration"/>

MyConditionalConfiguration看起来像

@Configuration
@Conditional(MyConditionalConfiguration.Condition.class)
@ImportResource("/com/example/context-fragment.xml")
public class MyConditionalConfiguration {
    static class Condition implements ConfigurationCondition {
         @Override
         public ConfigurationPhase getConfigurationPhase() {
             return ConfigurationPhase.PARSE_CONFIGURATION;
         }
         @Override
         public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
             // only load context-fragment.xml if the system property is defined
             return System.getProperty("com.example.context-fragment") != null;
         }
    }
}

最后,你将要包含的bean定义放在/com/example/context-fragment.xml中

2020-04-13
小编典典

在Spring 4之前,使用标准Spring组件可以获得的最接近的是:

<import resource="Whatever-${yyzzy}.xml"/>

${xyzzy}从系统属性中插入属性。(我使用了上下文加载程序类的hacky自定义版本,该版本在开始加载过程之前将其他位置的属性添加到系统属性对象中。)

但是,你也可以避免导入大量不必要的东西……并使用各种技巧仅使必需的bean实例化。这些技巧包括:

  • placeholder and property substitution
  • selecting different beans using the new Spring expression language,
  • bean aliases with placeholders in the target name,
  • lazy bean initialization, and
  • smart bean factories.
2020-04-13