设计:如何从程序中驱动一组动态的类似类

时间:2016-03-18 04:05:40

标签: java design-patterns

我必须在我的申请中做出设计决定。以下是该方案。

我有一组服务类,它们分布在我的应用程序中的不同maven模块中。

public class ServiceA 
{
   public void startA()
   {
       ....
   }
}

public class ServiceB
{
   public void startB()
   {
       ....
   }
}

我目前有8个这样的服务类。将来可能会添加更多。

所有这些服务类的启动必须在驱动程序中调用。 服务的数量可能会随着时间而变化。当它发生时,我想避免更新驱动程序。

我已经考虑过使用服务来实现接口。但是在运行时,驱动程序需要可以使用服务列表来启动它们。

当应用程序启动时,驱动程序是第一个被执行的驱动程序,并且可以启动服务。

请建议如何解决这个问题。

3 个答案:

答案 0 :(得分:1)

你可以转过来让所有服务自己注册到驱动程序。

它们都可以是注入驱动程序的春豆。

如果您不希望服务了解驱动程序,您可以为他们引入一个依赖于服务和驱动程序的中间人,或者您可以通过@Configuration类来引导它。 / p>

更新

您可以使用ServiceLoader类查找您的服务,查看此tutorial

这是一个使其更易于使用的库:ServicePluginLoader

答案 1 :(得分:0)

让他们都实现包含start()方法的通用接口。

在获得完全限定的类名后用Class.forName()加载它们,并通过反射(Class.newInstance())创建新实例,这将要求它们都具有no-arg构造函数。

Spring已经完成了类和实例管理部分,所以你应该对它进行调查,让你只需要担心常见的接口。

答案 2 :(得分:0)

创建配置类以仅检测和注册实现IsService接口的类。

@Configuration
@ComponentScan(basePackages = {"com.subex.roc"} , 
              useDefaultFilters = false , 
              includeFilters = {@Filter(type = FilterType.ASSIGNABLE_TYPE,value = IsService.class)})
public class ServiceRegisterConfig 
{
}

获取已注册的类并以多态方式调用start()。

public void initServerServices()
{
    AnnotationConfigApplicationContext context = new  AnnotationConfigApplicationContext();
    context.register(ServiceRegisterConfig.class);
    context.refresh();

    for (String beanDfn : context.getBeanDefinitionNames()) 
    {
      if (context.getBean(beanDfn) instanceof IsService) {
      IsService service = (IsService) context.getBean(beanDfn);
      service.start();
    }
 } 
}