До сих пор у меня было очень простое определение bean-компонента, которое выглядело так:
@Bean
@Conditional(value=ConditionClass.class)
SomeInterface myMethodImpl(){
return new ImplementationOne();
}
Однако теперь у меня возникла ситуация, когда был добавлен дополнительный класс реализации, назовем его ImplementationTwo
, который нужно использовать вместо ImplementationOne
, когда опция включена в файле конфигурации.
Так что мне нужно что-то вроде этого:
@Bean
@Conditional(value=ConditionClass.class)
SomeInterface myMethodImpl(){
return context.getEnvironment().getProperty("optionEnabled") ? new
ImplementationOne() : new ImplementationTwo();
}
По сути, способ создания экземпляра правильной реализации во время определения компонента на основе значения конфигурации. Возможно ли это, и может ли кто-нибудь привести пример? Спасибо
2 ответа
Это можно реализовать без использования @Conditional
.
Предполагая, что у вас есть интерфейс SomeInterface
и две реализации ImplOne
ImplTwo
:
SomeInterface.java
public interface SomeInterface {
void someMethod();
}
ImplOne.java
public class ImplOne implements SomeInterface{
@Override
public void someMethod() {
// do something
}
}
ImplTwo.java
public class ImplTwo implements SomeInterface{
@Override
public void someMethod() {
// do something else
}
}
Затем вы можете контролировать, какая реализация используется в классе конфигурации, например:
MyConfig.java
@Configuration
public class MyConfig {
@Autowired
private ApplicationContext context;
@Bean
public SomeInterface someInterface() {
if (this.context.getEnvironment().getProperty("implementation") != null) {
return new ImplementationOne();
} else {
return new ImplementationTwo();
}
}
}
Убедитесь, что сканирование компонентов пружины обнаруживает MyConfig
. Затем вы можете использовать @Autowired
, чтобы внедрить правильную реализацию в любое другое место вашего кода.
Я думаю, вы делаете это неправильно.
Вы должны использовать @Conditional()
в своей реализации, а не в интерфейсе.
Вот как я бы это сделал:
Интерфейс, который вы будете использовать в своем коде.
MyInterface.java
public interface MyInterface {
void myMethod();
}
Первая реализация:
MyInterfaceImplOne.java
@Bean
@Conditional(MyInterfaceImplOneCondition.class)
public class MyInterfaceImplOne implements MyInterface {
void myMethod(){
// dosmthg
}
}
MyInterfaceImplOneCondition.java
public class MyInterfaceImplOneCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return context.getEnvironment().getProperty("optionEnabled")
}
}
И для второй реализации:
MyInterfaceImplTwo.java
@Bean
@Conditional(MyInterfaceImplTwoCondition.class)
public class MyInterfaceImplTwo implements MyInterface {
void myMethod(){
// dosmthg 2
}
}
MyInterfaceImplTwoCondition.java
public class MyInterfaceImplTwoCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return !context.getEnvironment().getProperty("optionEnabled")
}
}
В этом случае вам просто нужно вызвать интерфейс, и Spring внедрит компонент, соответствующий правильному условию.
Надеюсь, это то, что вы ищете, и я был достаточно ясен!
Новые вопросы
java
Java - это язык программирования высокого уровня. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег редко используется отдельно и чаще всего используется вместе с [spring], [spring-boot], [jakarta-ee], [android], [javafx], [hadoop], [gradle] и [maven].