@Autowired и статический метод
У меня есть служба @Autowired
, которая должна использоваться из статического метода. Я знаю, что это неправильно, но я не могу изменить текущий дизайн, поскольку для этого потребуется много работы, поэтому для этого мне нужен простой хак. Я не могу изменить randomMethod()
как нестатический, и мне нужно использовать этот autwired bean. Любые подсказки, как это сделать?
@Service
public class Foo {
public int doStuff() {
return 1;
}
}
public class Boo {
@Autowired
Foo foo;
public static void randomMethod() {
foo.doStuff();
}
}
Ответы
Ответ 1
Вы можете сделать это, выполнив одно из следующих решений:
Использование конструктора @Autowired
В этом подходе будет построен bean, требующий некоторых beans в качестве параметров конструктора. В коде конструктора вы устанавливаете статическое поле со значением, полученным как параметр для выполнения конструктора. Пример:
@Component
public class Boo {
private static Foo foo;
@Autowired
public Boo(Foo foo) {
Boo.foo = foo;
}
public static void randomMethod() {
foo.doStuff();
}
}
Использование @PostConstruct для передачи значения в статическое поле
Идея здесь состоит в том, чтобы передать bean в статическое поле после bean, настроенного spring.
@Component
public class Boo {
private static Foo foo;
@Autowired
private Foo tFoo;
@PostConstruct
public void init() {
Boo.foo = tFoo;
}
public static void randomMethod() {
foo.doStuff();
}
}
Ответ 2
Вам нужно обходиться с помощью подхода к аксессурам с использованием статического приложения:
@Component
public class StaticContextAccessor {
private static StaticContextAccessor instance;
@Autowired
private ApplicationContext applicationContext;
@PostConstruct
public void registerInstance() {
instance = this;
}
public static <T> T getBean(Class<T> clazz) {
return instance.applicationContext.getBean(clazz);
}
}
Затем вы можете получить доступ к экземплярам bean статическим образом.
public class Boo {
public static void randomMethod() {
StaticContextAccessor.getBean(Foo.class).doStuff();
}
}
Ответ 3
Что вы можете сделать, это @Autowired
метод setter и установить новое статическое поле.
public class Boo {
@Autowired
Foo foo;
static Foo staticFoo;
@Autowired
public void setStaticFoo(Foo foo) {
Boo.staticFoo = foo;
}
public static void randomMethod() {
staticFoo.doStuff();
}
}
Когда обрабатывается bean, Spring вставляет экземпляр реализации Foo
в поле экземпляра Foo
. Затем он также вводит тот же экземпляр Foo
в список аргументов setStaticFoo()
, который будет использоваться для установки статического поля.
Это ужасное обходное решение и потерпит неудачу, если вы попытаетесь использовать randomMethod()
, прежде чем Spring обработал экземпляр Boo
.
Ответ 4
Это отстой, но вы можете получить bean с помощью интерфейса ApplicationContextAware
. Что-то вроде:
public class Boo implements ApplicationContextAware {
private static ApplicationContext appContext;
@Autowired
Foo foo;
public static void randomMethod() {
Foo fooInstance = appContext.getBean(Foo.class);
fooInstance.doStuff();
}
@Override
public void setApplicationContext(ApplicationContext appContext) {
Boo.appContext = appContext;
}
}
Ответ 5
Использовать AppContext. Убедитесь, что вы создаете bean в своем файле контекста.
private final static Foo foo = AppContext.getApplicationContext().getBean(Foo.class);
public static void randomMethod() {
foo.doStuff();
}