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

问题描述 投票:0回答:6

通过这堂课

@Component
public class Sample {

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


}

如果我尝试

Sample.name
,它总是“空”。所以我尝试了这个。

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
设置正确。这是好还是不好?如果不行的话还有什么更好的办法吗?以及如何做?

spring code-injection
6个回答
144
投票

首先,

public static
final
领域是邪恶。 Spring 出于某种原因不允许注入此类字段。

您的解决方法是有效的,您甚至不需要getter/setter,

private
字段就足够了。另一方面尝试这个:

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

(与

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


2
投票

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

Spring 在找到 @Value 注解时使用依赖注入来填充特定值。但是,它不是将值传递给实例变量,而是传递给隐式设置器。然后,该设置器处理 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;
    }
}

0
投票

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

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

0
投票

对于那些想要在 Spring Boot 应用程序的主类中使用 ApplicationContext 的人,您可以只使用

SpringApplication.run
的返回值。


0
投票

虽然可能需要实施变通办法,但如果可能的话,在大多数情况下应该尽量避免它们。 Spring 非常擅长处理依赖注入,并将大多数对象视为单例。这意味着 Spring 可以为您处理对象的创建,以及在运行时注入这些对象。当将此与 Spring 托管 bean 可能是 Singleton 的事实结合起来时,静态方法和变量的使用基本上是不必要的。您可以简单地在构造函数级别或变量级别自动装配您正在查找的对象的实例,并引用方法或变量的非静态版本。这是理想的情况,其行为与静态引用类似。非静态变量基本上是静态的,因为您在代码的每一部分中只使用了对象的一个实例,并且由于依赖注入,您永远不会处理对象的实例化,就像静态引用一样!伟大的!现在我确信在某些情况下您需要解决方法(即您没有使用依赖项注入或类不是单例),但如果可能的话尽量不要使用解决方法。而且这只是我的 2 美分。有人可能可以提供 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!");
    }
 }

0
投票

解决方案不符合声纳要求。构建不会通过。

© www.soinside.com 2019 - 2024. All rights reserved.