Весенний синглтон со свойством

Я хотел бы создать синглтон, содержащий MAC-адрес системы, в которой он работает, на основе предоставленного сетевого интерфейса.

Я написал следующий код:

public class NodeMac {

    private static final String INSTANCE = getMacAddress();

    private static String networkInterfaceName;

    @Value("${machine.network.interface}")
    public void setNetworkInterfaceName(String networkInterfaceName) {
        NodeMac.networkInterfaceName = networkInterfaceName;
    }

    private NodeMac() { }

    public static String getInstance() {
        return INSTANCE;
    }

    private static String getMacAddress() {
        try {
            NetworkInterface network = NetworkInterface.getByName(networkInterfaceName);

            byte[] mac = network.getHardwareAddress();

            System.out.print("Current MAC address : ");

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < mac.length; i++) {
                sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
            }
            return sb.toString();
        } catch (SocketException | NullPointerException e) {
            throw new RuntimeException(
                    "Failed to extract MAC address for network interface with name " + networkInterfaceName, e);
        }
    }
}

И в application.properties:

machine.network.interface=eno1

Однако я не могу найти способ получить значение свойства, содержащее имя сетевого интерфейса. Он всегда равен нулю, независимо от того, как я пытаюсь получить к нему доступ.

Как правильно это сделать? Наличие свойства в синглтоне - это антипаттерн?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
967
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Редактировать

Итак, вы изо всех сил пытаетесь создать класс pojo с одним экземпляром с введенным @Value. Если вы умеете работать с bean-компонентами, то это правильный путь:

@Component // This will default give you a single ton bean
public class NodeMac {

    @Value("${machine.network.interface}")
    private String networkInterfaceName;

    public String getMacAddress() {
        try {
            NetworkInterface network = NetworkInterface.getByName(networkInterfaceName);

            byte[] mac = network.getHardwareAddress();

            System.out.print("Current MAC address : ");

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < mac.length; i++) {
                sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
            }
            return sb.toString();
        } catch (SocketException | NullPointerException e) {
            throw new RuntimeException(
                    "Failed to extract MAC address for network interface with name " + networkInterfaceName, e);
        }
    }
}

СТАРЫЙ

Как вы пришли к этому выражению:

String key = System.getProperty("machine.network.interface");

Маловероятно, что машина имеет только один сетевой интерфейс, поэтому не может быть возвращен ни один ключ.

Действительно, оракул уже пишет учебник здесь

public static void main(String args[]) throws SocketException {
    Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
    for (NetworkInterface netint : Collections.list(nets))
        displayInterfaceInformation(netint);
}

static void displayInterfaceInformation(NetworkInterface netint) throws SocketException {
    out.printf("Display name: %s\n", netint.getDisplayName());
    out.printf("Name: %s\n", netint.getName());
    Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
    for (InetAddress inetAddress : Collections.list(inetAddresses)) {
        out.printf("InetAddress: %s\n", inetAddress);
    }
    out.printf("\n");
 }

Свойство содержит имя сетевого интерфейса. В данном случае eno1. Я хотел проверить, доступен ли ключ таким образом, поскольку аннотация Springs @Value всегда дает мне нулевое значение.

jokarl 23.05.2018 12:40

Ты не можешь. Поскольку ваш метод static будет запущен до автоподключения bean-компонентов

Mạnh Quyết Nguyễn 23.05.2018 12:42

Я не знал, что синглтон по умолчанию, спасибо. Мне нужно было только удалить модификатор static из инъекции значения в приведенном выше коде, и теперь он работает.

jokarl 23.05.2018 12:56

Да, Spring bean-компонент по умолчанию - singleton, если вы не указали, что он не является одноэлементным. Рад, что помог.

Mạnh Quyết Nguyễn 23.05.2018 12:59

Другие вопросы по теме