【问题标题】:Spring two different application context - property placeholder collisionSpring 两种不同的应用上下文——属性占位符冲突
【发布时间】:2016-06-17 23:04:25
【问题描述】:

我已经使用 Spring 框架创建了一个 SDK,它将被使用 与 REST 后端集成,利用依赖注入。

在这个 SDK 中,我有 MapPropertySources 来处理 PropertyPlaceHolders。 基本上我以编程方式在那里注册了一些我想要的属性 在 SDK 中使用 @Value 注释解决。

它在 SDK 中运行良好,但是当我构建 SDK 时(使用构建器) 在Spring-boot 应用程序中,来自MapPropertiesPlaceHolder 的属性 不再解决。

我有来自构建器类的这段代码:

    public MyRepository build() {


    AnnotationConfigApplicationContext context =
            new AnnotationConfigApplicationContext();

    StandardEnvironment env = new StandardEnvironment();
    context.setEnvironment(env);


    Map<String, Object> propertiesMap = new HashMap<>();
    propertiesMap.put("baseUrl", baseUrl);

    MutablePropertySources mutablePropertySources = context.getEnvironment().getPropertySources();
    mutablePropertySources.addFirst(new MapPropertySource("customPropertiesMap", propertiesMap));


    if(jerseyClient == null){
        jerseyClient = JerseyClientBuilder.createClient();
    }

    context.getBeanFactory().registerSingleton("jerseyClient", jerseyClient);

    context.setParent(null);
    context.register(MySdk.class);
    context.refresh();

    MySdk mySdk = new MySSdk(context);

    return mySdk;
}

这是我实例化 SDK 并创建新的方式 里面的Spring上下文。

问题是MapPropertySource内的属性 当我将 SDK 用作另一个中的 maven 依赖项时未解决 spring-boot 申请。这可能与父母有关 语境?只是没有解析属性...我应该在哪里调查?

问题很长,我在 SDK 的测试中解决了 @Value('${baseUrl}),但是当我将此 SDK 包含在另一个 spring-boot 应用程序中时,它将不再被解决。为什么?

编辑:

MySdk 类如下所示:

@ComponentScan
@Service
@PropertySource("classpath:application.properties")
public class DeviceRepository {

    private ApplicationContext context;

    public MySdk(){
    }

    public MySdk(ApplicationContext context) {
        this.context = context;
    }
    // other methods that calls beans from context like
    // this.context.getBean(MyBean.class).doSomething()

在同一个 SDK 中的测试中一切正常。这 baseUrl 属性解决得很好,但是当我将此 SDK 连接到另一个 spring 应用程序,在构建器中传递的属性,它们不是 由@Value 注释识别。

【问题讨论】:

  • 没有以这种方式加载属性,因为我通常使用属性文件或云配置运行,但您不应该将 MySdk 实例注册到上下文而不仅仅是类本身吗?
  • 我已经编辑了帖子,还添加了 MySdk 类。我确实对 spring 处理两个或更多上下文的方式感到奇怪,因为我遇到了问题。可能,我的 SDK 的上下文(在另一个 spring 上下文中实例化)在 AnnotationConfigApplicationContext 内部有一些我不知道的魔力......我期待这个 SDK 中的这个上下文与其他上下文隔离,但它看来Spring在背后做了太多的魔法……

标签: java spring dependency-injection spring-boot


【解决方案1】:

您是否在 Spring 配置中定义了 PropertySourcesPlaceholderConfigurer bean?每当 @Value 注释内的属性解析失败时,这是首先想到的事情之一。

@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
    return new PropertySourcesPlaceholderConfigurer();
}

Javadoc 链接:

http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/support/PropertySourcesPlaceholderConfigurer.html

【讨论】:

  • 这是对的,我调试的方向错了。我想spring boot会自动为你创建这个bean,但是如果你不使用spring boot而只使用spring framework,你必须创建它。不确定属性源的生命周期究竟如何,但问题不是因为我有 2 个弹簧上下文,就像我最初想的那样。
【解决方案2】:

hmm 刚刚阅读了一些关于利用属性占位符利用 java 配置的有趣内容。查看此链接#3。看来您必须注册另一个 bean。

http://www.baeldung.com/2012/02/06/properties-with-spring/

另外值得注意的是,还有关于子与父上下文的全范围讨论。我不相信你可以有两个上下文而不创建这种关系。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-06
    • 1970-01-01
    • 2013-05-05
    • 1970-01-01
    相关资源
    最近更新 更多