【问题标题】:Spring: How to inject a value to static field?Spring:如何向静态字段注入值?
【发布时间】:2011-11-07 09:30:47
【问题描述】:

有了这个类

@Component
public class Sample {

    @Value("${my.name}")
    public static String name;


}

如果我尝试Sample.name,它总是'null'。所以我尝试了这个。

public class Sample {

    public static String name;

    @PostConstruct
    public void init(){
        name = privateName;
    }

    @Value("${my.name}")
    private String privateName;

    public String getPrivateName() {
        return privateName;
    }

    public void setPrivateName(String privateName) {
        this.privateName = privateName;
    }  

}

此代码有效。 Sample.name 设置正确。这是好方法还是不好?如果没有,有没有更好的方法?又该怎么做呢?

【问题讨论】:

  • 这不会解决;如果在创建对象之前使用了静态变量。例如)如果在静态块下使用静态变量来构造资源,那么资源将被构造为null。

标签: spring code-injection


【解决方案1】:

此信息的来源是:https://www.baeldung.com/spring-inject-static-field

Spring 在找到 @Value 注解时使用依赖注入来填充特定的值。但是,不是将值传递给实例变量,而是将其传递给隐式 setter。然后这个 setter 处理我们的 NAME_STATIC 值的填充。

    @RestController 
//or if you want to declare some specific use of the properties file then use
//@Configuration
//@PropertySource({"classpath:application-${youeEnvironment}.properties"})
public class PropertyController {
 
    @Value("${name}")//not necessary
    private String name;//not necessary
 
    private static String NAME_STATIC;
 
    @Value("${name}")
    public void setNameStatic(String name){
        PropertyController.NAME_STATIC = name;
    }
}

【讨论】:

    【解决方案2】:

    如果想在Spring Boot应用的主类中使用ApplicationContext,可以直接使用SpringApplication.run的返回值。

    【讨论】:

      【解决方案3】:

      这是我加载静态变量的示例代码

      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.stereotype.Component;
      
      @Component
      public class OnelinkConfig {
          public static int MODULE_CODE;
          public static int DEFAULT_PAGE;
          public static int DEFAULT_SIZE;
      
          @Autowired
          public void loadOnelinkConfig(@Value("${onelink.config.exception.module.code}") int code,
                  @Value("${onelink.config.default.page}") int page, @Value("${onelink.config.default.size}") int size) {
              MODULE_CODE = code;
              DEFAULT_PAGE = page;
              DEFAULT_SIZE = size;
          }
      }
      

      【讨论】:

        【解决方案4】:

        首先,public staticfinal 字段是邪恶的。 Spring 不允许注入这些字段是有原因的。

        您的解决方法 是有效的,您甚至不需要 getter/setter,private 字段就足够了。另一方面,试试这个:

        @Value("${my.name}")
        public void setPrivateName(String privateName) {
            Sample.name = privateName;
        }  
        

        (适用于@Autowired/@Resource)。但是给你一些建设性的建议:用private 字段和getter 创建第二个类,而不是public static 字段。

        【讨论】:

        • 对于“public static non-final fields are evil”,你能给我一些参考吗?
        • 非最终意味着您可以修改字段值,对于静态字段,这意味着处理线程并发 - 也就是堆栈中的痛苦。
        • 如何在静态块中使用@Value?请指导我们...问候,内哈
        • 仅供参考:上面的代码将导致 Sonar / Checkstyle 违规(如果您对这种事情感到困扰),因为您有一个写入静态字段的实例方法。
        • 可以通过使用静态设置器来模仿最终方面,该设置器仅在当前为空时设置值。因此,您只允许对该字段进行一次修改。 (这当然是私有的,并使用吸气剂来访问它)。 Spring 可以在其配置阶段(XML 或 Annotation)调用静态方法。
        猜你喜欢
        • 1970-01-01
        • 2012-07-04
        • 2017-07-05
        • 1970-01-01
        • 1970-01-01
        • 2011-02-15
        • 2016-08-28
        • 2017-06-19
        相关资源
        最近更新 更多