@Autowired и статический метод
Я @Autowired
сервис, который должен использоваться из статического метода. Я знаю, что это неправильно, но я не могу изменить текущий дизайн, так как это потребует много работы, поэтому мне нужен простой хак для этого. Я не могу измениться randomMethod()
чтобы быть нестатическим, и мне нужно использовать этот autowired bean. Есть подсказки, как это сделать?
@Service
public class Foo {
public int doStuff() {
return 1;
}
}
public class Boo {
@Autowired
Foo foo;
public static void randomMethod() {
foo.doStuff();
}
}
5 ответов
вы можете сделать это, следуя одному из решений:
использование конструктора @Autowired
этот подход построит компонент, требующий некоторых компонентов в качестве параметров конструктора. В коде конструктора вы устанавливаете статическое поле со значением, полученным в качестве параметра для выполнения конструктора. Пример:
@Component
public class Boo {
private static Foo foo;
@Autowired
public Boo(Foo foo) {
Boo.foo = foo;
}
public static void randomMethod() {
foo.doStuff();
}
}
использование @PostConstruct для передачи значения статическому полю
идея здесь состоит в том, чтобы передать Боб статическому полю после того, как Боб настроено весной.
@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();
}
}
вы должны обойти это с помощью статического подхода к контекстному доступу приложения:
@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();
}
}
что вы можете сделать, это @Autowired
сеттера и установить новое статическое поле.
public class Boo {
@Autowired
Foo foo;
static Foo staticFoo;
@Autowired
public void setStaticFoo(Foo foo) {
Boo.staticFoo = foo;
}
public static void randomMethod() {
staticFoo.doStuff();
}
}
когда фасоль получает обработанной, Весна впрыснет Foo
экземпляр реализации в поле экземпляра foo
. Затем он также будет вводить то же самое Foo
экземпляр в setStaticFoo()
список аргументов, который будет использоваться для установки статического поля.
это страшное решение и не удастся, если вы попытаетесь использовать randomMethod()
перед весной обработал экземпляр Boo
.
это отстой, но вы можете получить Боб, используя 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;
}
}
Использовать AppContext. Убедитесь, что вы создали компонент в контекстном файле.
private final static Foo foo = AppContext.getApplicationContext().getBean(Foo.class);
public static void randomMethod() {
foo.doStuff();
}