Spring Boot应用程序:为什么不读取application.properties文件?

63

我有一个Spring Boot应用程序,可以在这里找到: https://github.com/christophstrobl/spring-data-solr-showcase/tree/4b3bbf945b182855003d5ba63a60990972a9de72

使用mvn spring-boot:run可以成功编译和运行。

但是,当我在Spring Tools Suite中点击“以Spring Boot应用程序运行”时,会出现一个错误,指出无法找到在application.properties文件中设置的${solr.host}

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'productServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.data.solr.showcase.product.ProductServiceImpl.setProductRepository(org.springframework.data.solr.showcase.product.ProductRepository); nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'productRepository': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'solr.host' in string value "${solr.host}"

我的 applications.properties 文件看起来像这样:

# SPRING MVC
spring.view.suffix=.jsp
spring.view.prefix=/WEB-INF/views/

# SOLR
solr.host=http://192.168.56.11:8983/solr

相关类看起来像这样(唯一使用$solr.host变量的地方)。此外,如果我直接使用SOLR服务器的IP地址(如注释中的代码),应用程序就可以正常启动。

相关类如下所示(唯一使用 $solr.host 变量的地方)。此外,如果我直接使用 SOLR 服务器的 IP 地址(如注释代码中所示),应用程序将能够正常启动。

* Copyright 2012 - 2014 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.solr.showcase.config;

import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.repository.config.EnableSolrRepositories;
import org.springframework.data.solr.server.SolrServerFactory;
import org.springframework.data.solr.server.support.MulticoreSolrServerFactory;

/**
 * @author Christoph Strobl
 */
@Configuration
@EnableSolrRepositories(basePackages = { "org.springframework.data.solr.showcase.product" })

public class SearchContext {

    @Bean
    public SolrServer solrServer(@Value("${solr.host}") String solrHost) {
        return new HttpSolrServer(solrHost);
    }

//  @Bean
//  public SolrServer solrServer(@Value("http://192.168.56.11:8983/solr") String solrHost) {
//      return new HttpSolrServer(solrHost);
//  }

    @Bean
    public SolrServerFactory solrServerFactory(SolrServer solrServer) {
        return new MulticoreSolrServerFactory(solrServer);
    }

    @Bean
    public SolrTemplate solrTemplate(SolrServerFactory solrServerFactory) {
        return new SolrTemplate(solrServerFactory);
    }

}

在这里我包括了那个“ProductRepository” -- 它在错误信息中提到 -- 尽管它并没有太多的作用...

* Copyright 2012 - 2014 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.solr.showcase.product;

import java.util.Collection;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.solr.core.query.Query.Operator;
import org.springframework.data.solr.repository.Query;
import org.springframework.data.solr.repository.SolrCrudRepository;
import org.springframework.data.solr.showcase.product.model.Product;

/**
 * @author Christoph Strobl
 */
interface ProductRepository extends SolrCrudRepository<Product, String> {

    @Query(fields = { SearchableProductDefinition.ID_FIELD_NAME, SearchableProductDefinition.NAME_FIELD_NAME,
            SearchableProductDefinition.PRICE_FIELD_NAME, SearchableProductDefinition.FEATURES_FIELD_NAME,
            SearchableProductDefinition.AVAILABLE_FIELD_NAME }, defaultOperator = Operator.AND)
    Page<Product> findByNameIn(Collection<String> names, Pageable page);

}

我的文件结构看起来很“标准”...代码在src/main/java等目录中。应用程序属性文件位于src/main/resources目录中。

非常感谢任何建议。

(快速补充:这是在嵌入式服务器Tomcat上运行)

21个回答

114

这个问题有些难以理解 - 其他回答对我指明方向非常有帮助。

尝试了建议的解决方法后,我深入查找并在“项目属性”->“Java构建路径”->“源”(选项卡)->“构建路径上的源文件夹:【排除部分】”中发现了这个。

**/application.properties

移除了排除设置后,问题得到了解决,并且在启动期间从application.properties文件中获取了值。

值得注意的是,从命令行(在包含.project文件的目录中)运行此操作可以避免排除问题并正常工作。

mvn spring-boot:run

谢谢!救了我的一天。我在pom.xml中有<directory>src/main/resources</directory><filtering>false</filtering>。 - Alex
<resources> <resource> <directory>src/main/resources</directory> <filtering>false或true都可以 - 奇怪</filtering> <includes> <include>**.*</include> </includes> </resource> </resources> - Alex
非常感谢,Spring Boot 会自动加载 application.properties 文件,但是我们不小心将其从类路径中排除了。 - Ajay Sharma
1
非常感谢!但是到底是什么原因导致了这个排除出现在第一位呢? - Marco Bolis
第一次使用Eclipse/STS创建“新Spring启动器项目”时出现了奇怪的行为。 - Del Pedro
显示剩余5条评论

28

对我来说,这是由于打包方式的问题导致的,打包方式为pom

我的pom.xml文件中有如下内容:

<packaging>pom</packaging>

如果您有类似的问题,

  1. 请移除spring-boot应用程序中的此项。

  2. 删除target文件夹或使用mvn clean命令。

  3. 然后运行mvn install命令。
  4. 检查target/classes/application.properties文件中的属性。

有没有一种方法可以使用POM打包,同时仍然保持解决方案处于工作状态? - Darek
似乎不是这样的:https://dev59.com/QYXca4cB1Zd3GeqPNMQB - Darek
谢谢,这个对我有用,但是为什么会导致问题呢?你能解释一下吗? - Tayab Hussain
“pom”包装类型通常用于多模块项目,因为模块本身不需要构建成jar文件。其他默认的包装类型是“jar”。 - undefined

25

我使用了Spring Boot 2.0.0,遇到了同样的问题。1.4.3版本下就完美运行。

原因是如果您定义了这个参数:

-Dspring.config.location=file:/app/application-prod.yml

Spring Boot现在不会添加默认位置进行搜索。

解决方案:

-Dspring.config.location=file:/app/application-prod.yml,classpath:application.yml

请参见:

  1. /org/springframework/boot/context/config/ConfigFileApplicationListener.java
  2. https://docs.spring.io/spring-boot/docs/2.0.1.BUILD-SNAPSHOT/reference/htmlsingle/#appendix

4
这个答案似乎是正确的。需要警告用户,文档(第76.3节)说明(在解释如何覆盖spring.config.location之后):“无论您在环境中设置什么,Spring Boot始终会按上述描述加载application.properties文件。”另一个选项是改用spring.config.additional-location - Adam Batkin
这是正确的答案,帮助了我很多。谢谢! - Yanick Nedderhoff

19

请在您的pom.xml文件中加入以下内容。这应该解决问题。

<build>
    <resources>     
        <resource>
            <directory>src/main/resources</directory>
            <includes>                      
                <include>**/*.properties</include>                  
            </includes>
        </resource>            
    </resources>
</build>

这对我有用,别忘了在之后运行 mvn install - fayssal el ansari

9

遗憾的是,这些方法对我没有帮助。将资源文件夹添加到类路径(Classpath)中在我的情况下解决了问题。

具体步骤如下:

  1. 选择您的Spring应用程序并打开运行配置(Run configurations)
  2. 选择类路径(Classpath)选项卡
  3. 选择用户条目(User Entries)
  4. 点击高级(Advanced)按钮
  5. 选择添加文件夹(Add Folders)并单击OK按钮
  6. 选择您的资源(resources)文件夹(/src/main/resources)并单击OK按钮

enter image description here


9
在您的@Configuration类中声明PropertySourcesPlaceholderConfigurer。
@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {

      return new PropertySourcesPlaceholderConfigurer();
}

并在您的属性资源路径中加上适当的注释。

@PropertySource("classpath:your.properties")

1
谢谢Dani - 如果我的情况很简单,这显然会起作用。尝试了这个方法但没有效果后,我继续探索并发现包含application.configuration的目录已在我下载的项目的Project Properties --> Java Build Path --> Source(选项卡)设置中被明确排除。一旦我取消了排除,application.properties就像预期的那样在启动时被读取了。 - jb62

8

我通过将资源文件夹添加到构建路径中解决了这个问题。

之前

enter image description here

请按如下操作进行:
  1. 点击“添加文件夹”...
  2. 添加资源文件夹

enter image description here


1
我遇到了这个问题。如果我从IntelliJ进行“重建”,它会将application.properties从我的src/test/resources文件夹复制到我的target/test-classes文件夹中,然后一切正常。但是,如果我从Maven构建,则它会从target/test-classes文件夹中消失,然后当Maven运行测试时,测试将失败,因为它找不到application.properties文件。经过多次反复,我终于意识到我的文件夹名称写错了(上面的不是拼写错误)。我使用了“src/test/reources/application.properties”而不是“src/test/resources/application.properties”。真是个痛苦的发现。以上的答案帮助我找到了问题所在,并最终注意到了错别字。并不像人们想象的那么明显。要小心这一点。

1

当我意外删除了属性文件后,发生了这种情况。更新Maven项目对我有用。


1

在IntelliJ上,我遇到了同样的问题。 我可以看到文件中已经连线的变量,但是当我启动SpringBoot应用程序时,它不会将其连线。

我通过删除.idea文件夹并使缓存无效化加以解决。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接