Spring boot 使用@Value注释访问Spring Boot application.properties

Spring boot 使用@Value注释访问Spring Boot application.properties,spring-boot,annotations,Spring Boot,Annotations,我已经通读了几乎所有我能找到的东西,出于某种原因,我不能完全集中我的大脑思考如何使这项工作。在现有项目中苦苦挣扎了2天后,我从Spring.io下载了Rest的入门内容 我在主文件夹中创建了一个resources文件夹,并添加了一个名为application.properties的文件,其中包含以下内容: my.setting = HELLOTHERE 然后,我修改了问候语类,如下所示: package hello; import org.springframework.beans

我已经通读了几乎所有我能找到的东西,出于某种原因,我不能完全集中我的大脑思考如何使这项工作。在现有项目中苦苦挣扎了2天后,我从Spring.io下载了Rest的入门内容

我在主文件夹中创建了一个resources文件夹,并添加了一个名为application.properties的文件,其中包含以下内容:

my.setting = HELLOTHERE
然后,我修改了问候语类,如下所示:

    package hello;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

@Component
public class Greeting {

    private long id;
    private String content;
    private String dooDad;
    public Greeting(long id, String content) {
        this.id = id;
        this.content = content;
    }

    public Greeting() {
        // TODO Auto-generated constructor stub
    }

    public long getId() {
        return id;
    }

    public String getContent() {
        return content;
    }

    public String getDooDad() {
        return dooDad;
    }
    @Autowired
    public void setDooDad(@Value("${my.setting}")String dooDad) {
        this.dooDad = dooDad;
    }
}
package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;

@SpringBootApplication
@Configuration
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
我修改了应用程序类,使其具有@Configuration注释,如下所示:

    package hello;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

@Component
public class Greeting {

    private long id;
    private String content;
    private String dooDad;
    public Greeting(long id, String content) {
        this.id = id;
        this.content = content;
    }

    public Greeting() {
        // TODO Auto-generated constructor stub
    }

    public long getId() {
        return id;
    }

    public String getContent() {
        return content;
    }

    public String getDooDad() {
        return dooDad;
    }
    @Autowired
    public void setDooDad(@Value("${my.setting}")String dooDad) {
        this.dooDad = dooDad;
    }
}
package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;

@SpringBootApplication
@Configuration
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
我没有修改GreetingController类,但为了完整起见,我将包含它:

package hello;

import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

    @RequestMapping("/greeting")
    public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) {
        return new Greeting(counter.incrementAndGet(),
                            String.format(template, name));
    }
}
当我运行应用程序并查看输出时,我希望看到dooDad的值,而它总是空的

{"id":1,"content":"Hello, mike!","dooDad":null}

如果您能帮我解决这个问题,我们将不胜感激。我确实发现,如果我在应用程序类中的变量上添加@Value注释,它将使用正确的值填充该变量,而不是在Greeting类中?

通过实例化对象
Greeting
自己,您正在绕过依赖项注入:

return new Greeting(counter.incrementAndGet(),
                            String.format(template, name));
因此,
问候语
对象中的
@组件
@值
注释没有做任何事情(对于此特定实例)

我建议采取以下措施:

my.setting = HELLOTHERE
  • 使问候对象成为标准POJO
  • 在构造函数中包含
    String dooda
  • 使用
    @Value(${my.setting}”)字符串dooDad
    作为
    问候语控制器中的字段
  • dooDad
    传递到新的问候对象中,如下所示:

    返回新的问候语(counter.incrementAndGet(), 格式(模板,名称),dooDad)


  • 更新:添加以说明实现OP所述设置的各种选项。

    您正在通过实例化对象
    问候语
    来绕过依赖项注入:

    return new Greeting(counter.incrementAndGet(),
                                String.format(template, name));
    
    因此,
    问候语
    对象中的
    @组件
    @值
    注释没有做任何事情(对于此特定实例)

    我建议采取以下措施:

    my.setting = HELLOTHERE
    
  • 使问候对象成为标准POJO
  • 在构造函数中包含
    String dooda
  • 使用
    @Value(${my.setting}”)字符串dooDad
    作为
    问候语控制器中的字段
  • dooDad
    传递到新的问候对象中,如下所示:

    返回新的问候语(counter.incrementAndGet(), 格式(模板,名称),dooDad)


  • 更新:添加以说明实现OP所述设置的各种选项。

    在这种特殊情况下非常有意义,但我也希望能够在接受JSON作为输入的端点上设置默认值。JSON不一定包含整个对象。在本例中,它可能只包含
    {“id”:0,“content”:“foo”}
    我希望Jackson使用
    @value
    设置dooDad值。如果我理解你的意思,那么我必须测试端点中dooDad的值,如果它为空,则将其设置为
    @value
    ?“难道没有别的办法吗?”迈克尔哈奇说。在该场景中,我们将RequestMethod更改为POST,并在RequestParam中设置一个默认值(正如您使用name参数所做的那样),这是最干净的方法。如果dooDad未提交任何值,则将使用默认值。现在,如果您坚持在属性文件中设置这个默认值,它会变得更详细一些,但是可以做到。有关详细信息,请参阅我的示例repo:主分支是简单的方法,但请检查特性分支中的属性文件方法。在这种特殊情况下,这非常有意义,但我也希望能够在接受JSON作为输入的端点上设置默认值。JSON不一定包含整个对象。在本例中,它可能只包含
    {“id”:0,“content”:“foo”}
    我希望Jackson使用
    @value
    设置dooDad值。如果我理解你的意思,那么我必须测试端点中dooDad的值,如果它为空,则将其设置为
    @value
    ?“难道没有别的办法吗?”迈克尔哈奇说。在该场景中,我们将RequestMethod更改为POST,并在RequestParam中设置一个默认值(正如您使用name参数所做的那样),这是最干净的方法。如果dooDad未提交任何值,则将使用默认值。现在,如果您坚持在属性文件中设置这个默认值,它会变得更详细一些,但是可以做到。有关详细信息,请参见我的示例repo:主分支是简单的方法,但请检查特性分支中的属性文件方法。