当前位置: 首页 > 知识库问答 >
问题:

Spring Boot配置属性不工作

程冥夜
2023-03-14

试图让spring boot@ConfigurationProperties注释工作起来,这让我感到非常困难。所以希望有人能为我澄清我做错了什么。我有一个Spring Boot应用程序,它在类路径上包含一个application.properties。它的价值在于

server.contextPath=/test/v1
server.port=8080

spring.profiles.active=dev
vendors=me

我有一个application.class,它有spring boot注释,位于包层次结构的顶部

package com.test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableConfigurationProperties
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
package com.test.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Component
@PropertySource("classpath:application.properties")
@ConfigurationProperties
public class GlobalProperties {

    private String vendors;

    public String getVendors() {
        return vendors;
    }

    public void setVendors(String vendors) {
        this.vendors = vendors;
    }
}
package com.test.controller;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.test.config.GlobalProperties;

@RestController
@Component
public class MController {


    //TODO should be wired in from properties file 
    @Autowired
    GlobalProperties props;


    private boolean vendorUnknown(String vendor) {
        if(props.getAllowedVendor().equalsIgnoreCase(vendor)) {
            return true;
        }
        return false;
    }

    @RequestMapping(value = "/test/{id}", method = RequestMethod.GET, produces = { "application/json" })
    public ResponseEntity<?> getStatus(
            @PathVariable String id) {
        //@RequestBody Bookmark input
        if(vendorUnknown("me")) {
        System.out.println("found");
    };
        return ResponseEntity.noContent().build();
    }

}

有人告诉我我做错了什么吗?

更新:

将上面的代码更改为一个带有测试类的更简单的版本以重新创建问题。请参阅下面的pom.xml和测试类

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.me.test</groupId>
    <artifactId>test-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.3.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- tag::actuator[] -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- end::actuator[] -->
        <!-- tag::tests[] -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- end::tests[] -->
    </dependencies>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <artifactId>maven-failsafe-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

测试类:

package com.test.controller;

import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;


@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class MControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @InjectMocks
    MController testController;

    @Before
    public void setup() {

        // this must be called for the @Mock annotations above to be processed
        // and for the mock service to be injected into the controller under
        // test.
        MockitoAnnotations.initMocks(this);

        this.mockMvc = MockMvcBuilders.standaloneSetup(testController).build();
    }

    @Test
    public void testPropertiesMsg() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/test/1").accept(MediaType.APPLICATION_JSON))
        .andExpect(status().isOk());
    }
}

共有1个答案

从焱
2023-03-14
  1. 删除@PropertySource。您可以保留@component,如果不保留,则指定@enableConfigurationProperties(GlobalProperties.class)
  2. TestController上不需要@component。但我认为您的问题是从哪里调用vendorunknown方法。代码中没有显示。如果从构造函数调用,则bean初始化尚未完成,globalproperties props确实为空。

编辑:

基于OP的编辑,这里有一个完全工作的解决方案。

demoApplication.java:

@SpringBootApplication
@EnableConfigurationProperties
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

demoController.java:

@RestController
public class DemoController {
    @Autowired
    private DemoProperties props;

    @GetMapping(value = "/", produces = APPLICATION_JSON_VALUE)
    public ResponseEntity<?> getVendor() {
        return ResponseEntity.ok(props.getVendors());
    }
}

demoProperties.java:

@ConfigurationProperties
@Component
public class DemoProperties {
    private String vendors;

    public String getVendors() {
        return vendors;
    }

    public void setVendors(String vendors) {
        this.vendors = vendors;
    }
}

应用程序.属性:

vendors=me

demoControllerTest.java:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class DemoControllerTest {
    @Autowired
    TestRestTemplate restTemplate;

    @Test
    public void testGenVendor() throws Exception {
        String vendor = restTemplate.getForObject("/", String.class);

        assertThat(vendor).isEqualTo("me");
    }
}

injectmocks会无人值守失败。了解为什么不应该使用InjectMocks注释来自动连接字段。

 类似资料:
  • 我需要从正在运行的实例中转储springboot应用程序属性,可以吗?我需要它的原因:我正在使用链接配置文件,但其中一个属性设置不正确。谢谢

  • 我希望将concur严格用作配置源。我正在使用spring cloud Consor配置来获取配置。我正在使用git2consul将文件加载到Consor并读取它们。根据spring云文档,我在构建中添加了以下内容。格拉德尔 并在我的application.properties 我面临的问题是,预期的属性没有加载到ConfigurationProperties bean中。在ConsultProp

  • 简介 Apache ShardingSphere 提供属性配置的方式配置系统级配置。 配置项说明 名称 数据类型 说明 默认值 sql-show (?) boolean 是否在日志中打印 SQL。 打印 SQL 可以帮助开发者快速定位系统问题。日志内容包含:逻辑 SQL,真实 SQL 和 SQL 解析结果。 如果开启配置,日志将使用 Topic ShardingSphere-SQL,日志级别是 I

  • 简介 Apache ShardingSphere 提供属性配置的方式配置系统级配置。 配置项说明 名称 数据类型 说明 默认值 sql-show (?) boolean 是否在日志中打印 SQL。 打印 SQL 可以帮助开发者快速定位系统问题。日志内容包含:逻辑 SQL,真实 SQL 和 SQL 解析结果。 如果开启配置,日志将使用 Topic ShardingSphere-SQL,日志级别是 I

  • 我试图初始化log4j记录器使用SpringIOC和使用财产onfigurator.configure配置记录器,但财产onfigurator.configure不工作。 我的问题是如何将配置(log4j.properties)传递给Logger类? 波姆。xml 混淆班 log4j。性质

  • 寻找在Springboot应用程序中配置多个配置文件特定属性文件的最佳方法。下面是一个例子: -资源  · --application.properties  · · · · · --德夫             --application-dev.properties             --ldap-dev.properties             --Quartz-Dev.Prope