是否可以使用spring Java @Configuration避免编译时依赖性?

时间:2017-04-29 18:49:01

标签: java spring maven

有没有办法使用基于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的配置的组合,我知道这是可能的)?

2 个答案:

答案 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的配置的组合)也是可能的。