У меня есть @Autowired
служба, которую нужно использовать из статического метода. Я знаю, что это неправильно, но я не могу изменить текущий дизайн, так как это потребует много работы, поэтому для этого мне нужен простой взлом. Я не могу изменить его randomMethod()
на нестатичность, и мне нужно использовать этот автосоединенный компонент. Есть подсказки, как это сделать?
@Service
public class Foo {
public int doStuff() {
return 1;
}
}
public class Boo {
@Autowired
Foo foo;
public static void randomMethod() {
foo.doStuff();
}
}
Ответы:
Вы можете сделать это, следуя одному из решений:
Использование конструктора @Autowired
При таком подходе будет создан компонент, требующий некоторых компонентов в качестве параметров конструктора. В коде конструктора вы устанавливаете статическое поле со значением, полученным в качестве параметра для выполнения конструктора. Образец:
Использование @PostConstruct для передачи значения в статическое поле
Идея здесь состоит в том, чтобы передать bean-компонент статическому полю после того, как bean настроен с помощью spring.
источник
Вы должны решить эту проблему с помощью метода доступа к статическому контексту приложения:
Затем вы можете получить доступ к экземплярам bean статическим способом.
источник
getBean
до инициализации контекста (NPE) или после того, как контекст с его компонентами будет уничтожен. Этот подход имеет то преимущество, что "уродливый" доступ к статическому контексту заключен в один метод / класс.Что вы можете сделать, так это
@Autowired
установить метод установки и установить новое статическое поле.Когда bean-компонент будет обработан, Spring вставит
Foo
экземпляр реализации в поле экземпляраfoo
. Затем он также вставит тот жеFoo
экземпляр вsetStaticFoo()
список аргументов, который будет использоваться для установки статического поля.Это ужасный обходной путь, и он потерпит неудачу, если вы попытаетесь использовать его
randomMethod()
до того, как Spring обработает экземплярBoo
.источник
setStaticFoo()
есть безFoo
параметра.Это отстой, но вы можете получить компонент, используя
ApplicationContextAware
интерфейс. Что-то вроде :источник
Это основано на ответе @Pavel, чтобы решить возможность того, что контекст Spring не инициализируется при доступе из статического метода getBean:
Важная часть здесь - это
initContext
метод. Это гарантирует, что контекст всегда будет инициализирован. Но учтите, чтоinitContext
это будет предметом спора в вашем коде, поскольку он синхронизируется. Если ваше приложение сильно распараллелено (например, серверная часть сайта с высоким трафиком), это может быть не лучшим решением для вас.источник
Используйте AppContext. Убедитесь, что вы создали bean-компонент в своем файле контекста.
источник