我正在使用带注解的SpringBeans,我需要在运行时选择不同的实现。
@Service
public class MyService {
public void test(){...}
}
例如,对于windows平台,我需要MyServiceWin extending MyService
,对于linux平台,我需要MyServiceLnx extending MyService
。
现在我只知道一个可怕的解决办法:
@Service
public class MyService {
private MyService impl;
@PostInit
public void init(){
if(windows) impl=new MyServiceWin();
else impl=new MyServiceLnx();
}
public void test(){
impl.test();
}
}
请考虑我只使用注解而不是XML配置。
8条答案
按热度按时间zhte4eai1#
1.实现自定义
Condition
对于
Windows
也是如此。2.在
Configuration
类中使用@Conditional
3.照常使用
@Autowired
rks48beu2#
您可以将bean注入移动到配置中,如下所示:
或者,您可以使用
windows
和linux
配置文件,然后使用@Profile
注解您的服务实现,如@Profile("linux")
或@Profile("windows")
,并为您的应用程序提供其中一个配置文件。djmepvbi3#
让我们创建一个漂亮的配置。
假设我们有Animal接口,我们有Dog和Cat实现。我们想写写:
但是我们应该返回哪个实现呢?
那么什么是解决方案呢?解决问题有很多方法。我会写如何一起使用**@Qualifier**和自定义条件。
首先,让我们创建我们的自定义注解:
配置:
注意我们的bean名称为AnimalBean。为什么我们需要这个bean?因为当我们注入Animal接口时,我们只需要写@Qualifier(“AnimalBean”)
另外,我们创建了自定义注解来将值传递给我们的自定义条件。
现在我们的条件看起来像这样(假设“Dog”名称来自配置文件或JVM参数或...)
最后注射:
wbgh16ku4#
将所有实现自动连接到带有
@Qualifier
注解的工厂中,然后从工厂返回所需的服务类。我的Windows服务:
我的Mac服务:
我的工厂:
如果你真的想玩点花样,你可以使用枚举来存储你的实现类类型,然后使用枚举值来选择你想要返回的实现。
然后,您的工厂可以进入应用程序上下文并将示例拉入它自己的Map中。当您添加一个新的服务类时,只需向枚举中添加另一个条目,这就是您所要做的全部工作。
现在,您可以将所需的类类型传递到工厂中,它将为您提供所需的示例。非常有帮助,特别是如果你想使服务通用。
snz8szmq5#
只需将
@Service
注解的类设置为条件:**仅此而已。**不需要其他显式的@Bean
方法。奇迹发生了。条件是正确的,它属于:在实现类。
然后,您可以像往常一样使用
Dependency Injection
,例如通过Lombok
的@RequiredArgsConstructor
或@Autowired
。把它放到你的应用程序中。yml:
👍仅示例化带有
FooCondition
**注解的实现。无幻像示例化。**👍relj7zay6#
我只是在这个问题上加了两分钱。请注意,不必像其他答案所显示的那样实现那么多java类。可以简单地使用@ConditionalOnProperty。示例:
把它放到你的应用程序中。yml:
q0qdq0h27#
MyService.java:
MyServiceConfig.java:
application.properties:
MyServiceTypes.java
在任何Bean/组件/服务等中使用例如:
ijxebb2r8#
AOP(AspectJ)解决方案
方面:
豆子:
pom.xml配置
参考:
https://viktorreinok.medium.com/dependency-injection-pattern-for-cleaner-business-logic-in-your-java-spring-application-f4ace0a3cba7