使用Spring设计Java库

我正在从现有程序中将一些function提取到一个单独的库中。 这个程序使用Spring进行dependency injection和其他任务,我也想继续在库中使用它。

这个库需要监视文件系统的更改,因此它将启动某种单独的线程来执行此操作。

我真的不知道我对库的初始化有什么选择:

  • 如何初始化库的上下文? 我不能假设库用户也会使用Spring,但我可以使用库分发Spring。

  • 如何管理文件系统监控线程? 期望程序实例化库的主类和调用init或类似的东西是好的设计吗?

如何初始化库的上下文? 我不能假设库用户也会使用Spring,但我可以使用库分发Spring。

这取决于您的库,以您需要的方式实例化spring。 这通常在您的接口入口点中完成,该入口点使用例如ClassPathXmlApplicationContext来委托例程来配置spring。 样本可以是

 public class SpringContextLoader { private static ApplicationContext ctx = null; public static void init() { if (ctx == null) { ctx = ClassPathXmlApplicationContext("classpath:/applicatonContext.xml"); } } } 

如何管理文件系统监控线程? 期望程序实例化库的主类和调用init或类似的东西是好的设计吗?

在这种情况下,您可能会提供一个非守护程序线程,例如,一个必须手动终止的线程,以便应用程序干净地退出。 因此,您应该提供startstop机制。 在你的情况下,这些最好被称为registerEventListenerunregisterAllEventListener (因为我猜你想把文件系统事件传递给客户端……)。 另一种选择可以是使用带弹簧的quartz调度。

如何初始化库的上下文? 我不能假设库用户也会使用Spring,但我可以使用库分发Spring。

我正在使用Spring上下文编写一个库,我做了类似的事情,假设您的库名为FooLib ,有两个名为FooServiceBarService的服务,以及一个名为SpringContext的类,它通过java config配置您的spring上下文:

 public final class FooLib { private static ApplicationContext applicationContext; private FooLib() { } public static FooService getFooService() { return getApplicationContext().getBean(FooService.class); } public static BarService getBarService() { return getApplicationContext().getBean(BarService.class); } private static ApplicationContext getApplicationContext() { if (applicationContext == null) { applicationContext = new AnnotationConfigApplicationContext(SpringContext.class); } return applicationContext; } } 

然后客户端可以这样使用BarService

 BarService barService = FooLib.getBarService(); 

如何管理文件系统监控线程? 期望程序实例化库的主类和调用init或类似的东西是好的设计吗?

例如,您可以在SpringContext类的Spring上下文中静态启动监视子系统。

 @Configuration @ComponentScan(basePackages = "com.yourgroupid.foolib") public class SpringContext { @Bean public MonitoringSystem monitoringSystem() { MonitoringSystem monitoringSystem = new MonitoringSystem(); monitoringSystem.start(); return monitoringSystem; } } 

这应该足够了,因为Spring默认会急切地创建它的bean。

干杯

如何初始化库的上下文? 我不能假设库用户也会使用Spring,但我可以使用库分发Spring。

您可以使用PropertyPlaceholderConfigurer从(可能是外部的)属性文件中读取配置设置,该文件可由用户编辑。 这样用户就不会暴露于Spring的细节,甚至不会暴露给XML配置文件。

如何管理文件系统监控线程? 期望程序实例化库的主类和调用init或类似的东西是好的设计吗?

我建议使用Java并发框架,特别是ScheduledExecutorService ,以指定的时间间隔运行监视任务。 但是,您可能希望通过仅暴露一些init方法传递所需的计时器间隔来从库的用户隐藏此实现细节。

据我所知,无法将库配置为自动启动线程,您必须将类定义为起点。 使用Maven,您可以创建一个可执行jar: http : //maven.apache.org/plugins/maven-shade-plugin/examples/executable-jar.html在您的主类中,简单使用:

 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:myspring-context.xml"); context.registerShutdownHook(); 

对于线程,您可以尝试实现runnable接口,并初始化使用spring任务执行程序启动线程的bean。 我建议的更优雅的解决方案是将您的线程创建为pojo然后使用spring任务调度程序,如下所示:

       

我希望它会有所帮助。