有没有办法使用基于Spring Java的配置来声明bean而无需编译时检查,这样我就可以在运行时提供接口实现?
例如,当我编写JAX-RS客户端时,我使用JAX-RS API而不引用特定的API实现。在我的spring XML配置中,我然后声明了我想要使用的JAX-RS API的实际实现,例如泽西,在设置客户端bean时。因为在运行时使用(并验证)基于XML的配置,所以我不需要编译时依赖于Jersey。这允许我对Jersey有"if".equals(text)
Maven依赖,而我必须对JAX-RS API有<scope>runtime</scope>
依赖。这种方法的好处是,如果我不小心使用了实现,我的应用程序将无法使用Maven进行编译。
另一方面,如果我使用基于Java的spring配置(使用<scope>compile</scope>
)来声明我的bean,我必须对API的实现有编译时依赖性,因为配置本身是编译的。
如果使用基于Java的配置无法实现这一点,是否有其他选择(除了使用基于XML和Java的配置的组合,我知道这是可能的)?
答案 0 :(得分:2)
简短回答:
是的,可能:)
长答案:
除了描述的方法之外,Spring Boot还提供了开箱即用的功能。
这是Spring Boot实现自动配置魔术的方式。许多选项仅在编译时在核心Spring Boot Starter库中提供。但是在运行时期间必要的库(或精确的类)在类路径上可用时,对实际实现变得活跃。
Spring Boot为此提供了专门的注释:@ConditionalOnClass
。
我建议阅读Spring blog-post文档以熟悉该主题。
答案 1 :(得分:1)
要编译java配置,必须在编译时可以访问其中包含的所有类。
您可以将@Configuration根类移动到另一个maven模块,单独编译主模块和特定模块,并且不具备您不希望在主模块中拥有的依赖项;然后引用加载Spring上下文的特定@Configuration根类(例如,通过contextConfigLocation
上下文参数)。
或者您可以在@Configuration中使用脏Class.forName()
+ newInstance()
种技术。
当然,你提到的选项(@Configuration +基于XML的配置的组合)也是可能的。