是否可以在Spring框架中使用Java配置编写类似Guice的模块?
我想知道是否有一种折衷方案允许您模拟/利用GoogleGuice风格的EDSL编写模块的方式,这种方式在Spring中将接口绑定到实现 例如,假设我有一个Google Guice模块,看起来像这样:是否可以在Spring框架中使用Java配置编写类似Guice的模块?,java,spring,dependency-injection,guice,Java,Spring,Dependency Injection,Guice,我想知道是否有一种折衷方案允许您模拟/利用GoogleGuice风格的EDSL编写模块的方式,这种方式在Spring中将接口绑定到实现 例如,假设我有一个Google Guice模块,看起来像这样: public class BillingModule extends AbstractModule { protected void configure() { bind(BillingService.class).to(RealBillingService.class);
public class BillingModule extends AbstractModule {
protected void configure() {
bind(BillingService.class).to(RealBillingService.class);
}
}
这将BillingService
接口绑定到realblingservice
实现
我认为利用Spring的Java配置类可以做到的一个方法是
@Configuration
public class BillingConfiguration {
@Bean
public BillingService getRealBillingService() {
return new RealBillingService();
}
}
我想知道是否有更好的方法来实现这一点,或者随着使用的日益复杂,这种方法是否会失效
我真的很喜欢GoogleGuice以及它如何进行依赖注入,但这就是它的全部功能。Spring做的更多(是的,它的依赖注入机制仍然没有Guice“好”,但不可否认的是,我们希望利用一些伟大的项目,如Spring数据、Spring数据REST等,这样就不需要编写大量的样板代码。我使用了
Guice
和Spring
两种。据我所知,您在问题中展示的spring用法是实现与使用spring在Guice中绑定相同功能的唯一方法。如果需要注入依赖项,您可以始终将它们作为参数包含到@Bean
方法中,并让spring为您注入它们
它肯定没有那么干净,但它的工作原理是一样的。需要注意的一个关键问题是,spring中的默认范围是
单例
,而不是每次都有一个新实例(spring调用这个范围原型
)方法是使用@Profile
来包含同一接口的不同实现
一个简单的例子是DataSource
。但是,这可以很容易地扩展到具有多个实现的任何其他接口
例如:
@Configuration
public class LocalDataConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
.addScript("classpath:com/bank/config/sql/schema.sql")
.addScript("classpath:com/bank/config/sql/test-data.sql")
.build();
}
}
然后用于生产:
@Configuration
@Profile("production")
public class JndiDataConfig {
@Bean
public DataSource dataSource() throws Exception {
Context ctx = new InitialContext();
return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
}
}
然后,您所需要做的就是在启动应用程序上下文时声明哪些配置文件处于活动状态,并在需要它的地方
@Inject
/@Autowir
eDataSource
。您可以签出。虽然我找不到任何证据表明它曾经被发布过:-(@peeskillet)两者都使用是一种折衷方案。但不幸的是,这种折衷方案给我可怜的同事带来了困惑-(仅供参考,这里有一个相反的问题spring profiles->guice@PaulSamsotha截至2020年12月,spring guice已经发布了一些版本:不幸的是,这个答案没有解决原始问题的两个重要元素:(1)如何以编程方式在spring中生成配置(即,通过调用Guice中的binder方法),以及(2)如何将对象创建牢牢地掌握在DI框架的手中(返回新RealBillingService()的@Bean
方法仍然与Guice的绑定(BillingService.class)不同。to(RealBillingService.class)
方法不涉及创建任何对象)