Spring:如何向静态字段注入值?

Posted

技术标签:

【中文标题】Spring:如何向静态字段注入值?【英文标题】:Spring: How to inject a value to static field? 【发布时间】: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。 【参考方案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)调用静态方法。

以上是关于Spring:如何向静态字段注入值?的主要内容,如果未能解决你的问题,请参考以下文章

在 Spring 中为静态常量注入值

Spring-如何给静态变量注入值

如何使弹簧将值注入静态字段

spring 读取配置文件,将值注入到静态字段

Spring如何通过XML向队列注入值

spring 项目中在类中注入静态字段