Wiosna: Jak wstrzyknąć wartość do pola statycznego?

90

Z tą klasą

@Component
public class Sample {

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


}

Jeśli spróbuję Sample.name, zawsze jest to „zerowe”. Więc spróbowałem tego.

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

}

Ten kod działa. Sample.namejest prawidłowo ustawiony. Czy to dobry sposób, czy nie? Jeśli nie, czy jest coś lepszego? A jak to zrobić?

Whiteship
źródło
To nie rozwiąże; jeśli zmienna statyczna jest używana przed utworzeniem obiektu. np. jeśli zmienna statyczna jest używana w bloku statycznym do konstruowania zasobu, wówczas zasób zostanie skonstruowany z wartością null.
Kanagavelu Sugumar

Odpowiedzi:

115

Przede wszystkim public staticnie- finalpola są złe . Wiosna z jakiegoś powodu nie pozwala na wtryskiwanie na takie pola.

Twoje obejście jest prawidłowe, nie potrzebujesz nawet metody pobierającej / ustawiającej, privatewystarczy pole. Z drugiej strony spróbuj tego:

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

(działa z @Autowired/ @Resource). Ale żeby dać ci konstruktywną radę: stwórz drugą klasę z privatefield i getter zamiast public staticfield.

Tomasz Nurkiewicz
źródło
9
Czy mógłbyś podać mi jakieś odniesienia, ponieważ „publiczne statyczne pola nieokreślone są złe”?
Anderson
7
Niedokończenie oznacza, że ​​możesz zmodyfikować wartość pola, co w przypadku pola statycznego oznacza obsługę współbieżności wątków - czyli bólu stosu.
Xavier Portebois
Jak używać @Value z blokiem Static? Uprzejmie prowadź nas ... Pozdrawiam, Neha
4
Do Twojej wiadomości: powyższy kod spowoduje naruszenie Sonar / Checkstyle (jeśli przejmujesz się tego typu rzeczami), ponieważ masz metodę instancji piszącą do pola statycznego.
Neil,
Możliwe jest naśladowanie ostatniego aspektu za pomocą metody ustawiającej statycznej, która ustawi wartość tylko wtedy, gdy jest obecnie pusta. Więc zezwalasz tylko na jedną modyfikację pola. (co oczywiście zostało ustawione jako prywatne i użyj gettera, aby uzyskać do niego dostęp). Spring może wywołać metodę statyczną w swojej fazie konfiguracji (XML lub Annotation).
Walfrat
0

To jest mój przykładowy kod do ładowania zmiennej statycznej

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;
    }
}
Thành Nguyễn
źródło
-2

Spring używa iniekcji zależności, aby wypełnić określoną wartość, gdy znajdzie adnotację @Value. Jednak zamiast przekazywać wartość do zmiennej instancji, jest ona zamiast tego przekazywana do niejawnej metody ustawiającej. Ten ustawiający obsługuje następnie populację naszej wartości 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;
    }
}
Vitalii Shramko
źródło