我通过将一些共享组件(Web服务客户端)移动到库中来重构使用Spring的应用程序。组件无法自行运行,因此仍需要使用该库的应用程序中的某些bean。这是什么最好的做法?
我创建了一个@Configuration类,因此应用程序只需要@Import它来使用该库,但是应用程序还需要提供一个Jackson ObjectMapper和一个包含如何联系web服务的Settings对象。我将ObjectMapper和Settings bean自动装配到库中使用的各种bean中。应用程序通过将Client注入其代码并调用它来使用该库。
这样可行,但我不确定它是不是正确的风格。在IntelliJ IDEA中,当我开发库时,它抱怨库注入的bean不存在红色下划线,这是真的,它们不存在。但通常当我看到所有无法解决的文件都是红色的时候,这告诉我也许我没有采用正确的方式。
库需要与使用Spring 3和5的应用程序一起使用。如果某个库不适合定义自己的应用程序(例如,因为应用程序已经有杰克逊)和"专有"像Settings对象一样的bean?
答案 0 :(得分:2)
你的问题有点宽泛,但希望我能给你一个正确方向的暗示。
组件无法自行运行,因此仍需要使用该库的应用程序中的某些bean。这是什么最好的做法?
这解决了这个问题。在应用程序中使用库的接口和显式配置。以及向lib添加所需配置的良好文档。
答案 1 :(得分:1)
使用来自@Kayaman和@Ralph的灵感,我认为将Spring作为直接从应用程序上下文中使用的库的一部分公开是不合适的。我现在意识到这也不合适,因为图书馆可能会定义重复的私人"它不想暴露的豆子。我在思考它。如果我想使用Spring,我发现我可以这样做:
public class Factory {
public static Client createClient(ObjectMapper mapper, Settings settings) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerSingleton("mapper", mapper);
beanFactory.registerSingleton("settings", settings);
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(beanFactory);
ctx.registerBean(ClientConfiguration.class);
ctx.refresh();
return ctx.getBean(Client.class);
}
}
基本上,将Spring用作实现细节是可以的。由于我的配置只暴露了一个bean,因此它作为工厂方法是有意义的。在应用程序中,我将创建一个这样的方法:
@Bean public Client makeClient(ObjectMapper mapper, Settings settings) {
return Factory.createClient(mapper, settings);
}
当然,Bean方法将从应用程序的上下文中注入ObjectMapper和Settings,或者可以是ObjectMapper / Settings的内联构造函数。
相反,我决定的是因为客户端没有足够的bean而且没有一个是懒惰的,我只是完全删除了Spring注释,并且手动构建了对象图,几乎和spring上下文一样多。现在,该库的好处是在运行时根本不需要Spring,在一个假定的非Spring应用程序中。