Java 如何根据现场可用性注入应用程序、属性和价值?

Java 如何根据现场可用性注入应用程序、属性和价值?,java,spring,spring-boot,spring-mvc,Java,Spring,Spring Boot,Spring Mvc,我正在开发一个spring启动应用程序。在这个应用程序中,我使用以下代码创建了application.properties作为Springbean 情景1 应用程序属性 http.port =8080 http.port =8080 https.port=8081 ApplicationPropertyHandler @PropertySource("config/application.properties") @Component public class ApplicationProp

我正在开发一个spring启动应用程序。在这个应用程序中,我使用以下代码创建了application.properties作为Springbean

情景1

应用程序属性

http.port =8080
http.port =8080
https.port=8081
ApplicationPropertyHandler

@PropertySource("config/application.properties")
@Component
public class ApplicationPropertyHandler
{
    @Value("${http.port}")
    private String nonSecurePort;

    @Value("${https.port}" required=false)
    private String securePort;

    @Value("${server.servlet.context-path}")
    private String contextPath;

    @Value("${security.key}")
    private String securityKey;


}
@PropertySource("config/application.properties")
@Component
public class ApplicationPropertyHandler
{
    @Value("${http.port}")
    private String nonSecurePort;

    @Value("${https.port}" required=false)
    private String securePort;

    @Value("${server.servlet.context-path}")
    private String contextPath;

    @Value("${security.key}")
    private String securityKey;
场景2

当我保护应用程序时,https.port将写入application.properties

http.port =8080
http.port =8080
https.port=8081
应用程序属性

http.port =8080
http.port =8080
https.port=8081
ApplicationPropertyHandler

@PropertySource("config/application.properties")
@Component
public class ApplicationPropertyHandler
{
    @Value("${http.port}")
    private String nonSecurePort;

    @Value("${https.port}" required=false)
    private String securePort;

    @Value("${server.servlet.context-path}")
    private String contextPath;

    @Value("${security.key}")
    private String securityKey;


}
@PropertySource("config/application.properties")
@Component
public class ApplicationPropertyHandler
{
    @Value("${http.port}")
    private String nonSecurePort;

    @Value("${https.port}" required=false)
    private String securePort;

    @Value("${server.servlet.context-path}")
    private String contextPath;

    @Value("${security.key}")
    private String securityKey;
场景1:我得到了以下异常

org.springframework.beans.factory.BeanCreationException:错误 创建名为ApplicationPropertyHandler的bean:注入 自动连线依赖失败;嵌套异常是 java.lang.IllegalArgumentException:无法解析占位符 值“${https.port}”中的“https.port”


是否可以在application.properties中不使用字段https.port来运行场景1?

您可以使用空默认值
@value
,如前所述:

@Value("${https.port:#{null}}")
private String securePort;
如果不存在,则注入nullsecurePort

您可以检查:

或尝试以下操作之一:

1) @Value("${https.port:#{null}}")

2) @Value("${https.port:value-by-default-if-property-not-exist}")
第一个将注入null而不是字符串,第二个是“如果属性不存在,则默认值”


如果“application.properties”文件位于/resources/config文件夹中,则p.S.应起作用。

您可以使用以下代码-如果未找到属性,则将securePort变量与空字符串绑定,如果找到属性,则取配置的值。在这两种情况下,应用程序的启动都不会受到影响

@Component
@PropertySource("config/application.properties")
@ConditionalOnProperty("https.port")
public class ApplicationPropertyHandler {

    @Value("${http.port}")
    private String nonSecurePort;

    @Value("${https.port}")
    private String securePort;

    @Value("${security.key}")
    private String securityKey;
}
@Value("${https.port:}")
private String securePort;

我认为真正的问题是,您如何处理应用程序属性Handler

一个可能的解决方案是根本不使用值,答案中没有给出值,所以我将其添加到这里

那么,从你的问题来看:

  • 你有弹簧靴吗
  • 您可以使用配置维护application.properties文件
但是,然后您自己进行所有映射(将每个属性映射到值)

而不是使用<代码> @值< />代码>(实际上在SCORE之后可以指定默认值):“就像我们的许多同事所陈述的那样”考虑使用内置的Spring启动功能:


@SpringBootAppplication
@EnableConfigurationProperties(MyConfigurationProperties.class)
public class Main {
   public static void main(String [] args){...}
}

@ConfigurationProperties 
public class MyConfigurationProperties {


   public static class Http {
       private int port = 8080; // getters/setters, 0 is a default
   }

   public static class Https {
       private int port = 0; // getters/setters, 0 is a default
   }

   ....
}
这允许:

  • 调试(您可以放置断点并查看属性的实际情况)
  • 在IDE中编辑application.properties文件时自动完成(如果向maven/gradle添加特殊依赖项)
  • 轻松指定默认值(无需SPEL)
  • 松装

在上一个春季启动版本中,您完全可以将此设置为不可变,但我不知道您是否在上一个版本中,因此这超出了答案的范围。

尝试将application.properties替换为resources,而不是将Folder配置为Direct answer,不,如果应用程序属性中没有属性,则无法读取该属性。您必须定义key with或without value is您的选择第一个场景https.port不在application.properties文件中该属性在场景1中不需要运行代码