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

dbf7pr2w  于 2023-09-29  发布在  Spring
关注(0)|答案(5)|浏览(119)

与该类

@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已正确设置。这样好不好?如果没有,还有更好的方法吗?怎么做?

kiayqfof

kiayqfof1#

首先,public staticfinal字段是邪恶。Spring不允许注入到这样的字段是有原因的。
你的 * 解决方法 * 是有效的,你甚至不需要getter/setter,private字段就足够了。另一方面,试试这个:

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

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

gmxoilav

gmxoilav2#

此信息的来源是: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;
    }
}
ewm0tg9j

ewm0tg9j3#

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

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;
    }
}
uqzxnwby

uqzxnwby4#

对于那些想要在Sping Boot 应用程序的主类中使用ApplicationContext的人,您可以只使用SpringApplication.run的返回值。

ttcibm8c

ttcibm8c5#

尽管可能需要实现变通方法,但在大多数情况下,应尽可能避免使用它们。Spring非常擅长处理依赖注入,并将大多数对象视为单例。这意味着Spring可以为您处理对象的创建,以及在运行时注入这些对象。当将这一点与Spring托管bean可能是Singleton的事实结合起来时,静态方法和变量的使用在很大程度上是不必要的。您可以简单地在构造函数级或变量级查找对象的示例中自动连接,并引用方法或变量的非静态版本。这是理想的,其行为类似于静态引用。非静态变量基本上是静态的,因为你在代码的每一部分都只使用对象的一个示例,而且由于依赖注入,你永远不会处理对象的示例化,就像静态引用一样!太好了!现在我确信有一些情况下你需要解决这个问题(即:你没有使用依赖注入或者类不是单例),但是如果可能的话尽量不要使用变通方法。这也只是我的两分钱。有人可能会提供3。(:

public class InjectableClass{
     @Value("${my.value}")
     private String myString;
    
     public String nonStaticMethod(){
           return myString;
     }
}

public class LogicClass{
    private InjectableClass injectableClass;
    @Autowire
    public LogicClass(InjectableClass injectableClass){
       this.injectableClass = injectableClass;
    }

    public void logicClassMethod(){
        System.out.println("Hey! Here is the value I set on myString: " + 
                         injectableClass.nonStaticMethod() + ". That was 
                          basically like using a static method!");
    }
 }

相关问题