Почему мы не можем автоматически подключать статические поля весной?

96

Почему мы не можем автоматически подключить статическую переменную экземпляра в компоненте Spring. Я знаю, что есть другой способ добиться этого, но просто хочу знать, почему мы не можем сделать это описанным ниже способом.

например

@Autowired
public static Test test;
Ашу
источник
не могли бы вы пролить свет на альтернативный способ, о котором вы говорите.
samshers
Вы можете выполнить автоматическое подключение через конструктор или использовать @PostConstuct
gagarwa,

Ответы:

69

Поскольку использование статических полей поощряет использование статических методов. А статические методы - зло. Основная цель внедрения зависимостей - позволить контейнеру создавать объекты за вас и связывать их. Также это упрощает тестирование.

Как только вы начнете использовать статические методы, вам больше не нужно создавать экземпляр объекта, и тестирование станет намного сложнее. Также вы не можете создать несколько экземпляров данного класса, каждый со своей внедряемой зависимостью (потому что поле неявно разделяется и создает глобальное состояние - также зло).

Томаш Нуркевич
источник
11
Единственное предостережение, с которым я столкнулся, - это во время тестирования. Если вы хотите использовать @BeforeClassSpringJUnit4ClassRunner и использовать этот метод для доступа к bean-компонентам @Autowiredв тесте ... вы в принципе не можете. Что раздражает.
Джейсон Политес,
4
Этот ответ объясняет, почему этого не следует делать. Но настоящий мотив состоит в том, что, когда фреймворк пытается связать статический класс с компонентом, он может еще не быть загружен загрузчиком классов.
Андреа Т.
51
Этот ответ совершенно бессмысленный. Spring не навязывает вашу стратегию тестирования. Ответ заключается в том, что библиотека Spring еще не загружена, когда статический класс создается загрузчиком классов.
Андреа Т.
7
Ответ @AndreaT должен быть принятым ответом.
Chirag Agrawal
3
Статические методы тестировать ЛЕГЧЕ, не сложнее. Автоматическая вставка зависимостей в Spring кажется приятным, но на самом деле это более сложный путь для тестирования. Моки, заглушки и тестовые двойники - это запах кода, а не статические методы.
mttdbrd
150

Поскольку, когда загрузчик классов загружает статические значения, контекст Spring еще не обязательно загружается. Таким образом, загрузчик классов не будет правильно вводить статические поля в bean-компонент и завершится ошибкой.

Андреа Т
источник
47
Спасибо за ответ, который, кажется, действительно отвечает на вопрос, а не просто выражает мнение о том, что половина языка Java - плохая идея.
Уоррен Дью
1
"статический класс"?
Arun Raaj
Это не кажется правильным, поскольку Mockito может вводить объекты в статические поля, аналогично тому, как Spring выполняет автоматическое подключение ... хотя я не знаю, такая же реализация. Нужна дополнительная информация.
gagarwa,
Mockito не может имитировать статические методы. Вам нужно использовать Powermock для имитации статических методов
Джейсон Варгезе,
17

Согласно концепции ООП, если статические переменные подключены автоматически, это будет плохой дизайн.

Статическая переменная не является свойством объекта, но является свойством класса. Пружинная автоматическая разводка проводится на объектах, что, на мой взгляд, делает дизайн чистым. Вы можете развернуть объект автоматически подключенного компонента как одноэлементный и добиться того же результата, что и статический.

Субин Себастьян
источник
15

С помощью этого решения вы можете автоматически подключать статические поля весной.

@Component
public class TestClass {

    private static Test test;

    @Autowired
    public void setTest(Test test) {
        TestClass.test = test;
    }
}
Парф Соланки
источник
4
Bugfinder будет жаловаться на настройку статического поля нестатическим методом.
Neftanic
@Neftanic, ссылаясь на статические члены из нестатических, работает, обратное - нет
younes zeboudj