【问题标题】:Service Provider Interface in Java EnterpriseJava Enterprise 中的服务提供者接口
【发布时间】:2014-05-26 23:37:16
【问题描述】:

我想通过使用服务提供者接口来编写一个非常模块化的工厂,这样就不必每次都修改工厂本身。

为此,我想接收所有实现接口的具体类的列表,并在运行时通过每个方法调用决定使用哪个具体类,直到我有合适的实现者。

示例:我有一个interface Poligon
和混凝土Class Triangle implements Poligon。判别方法是:

boolean isSuitableFor(int i) {
    if (i == 3) 
      return true; 
    else 
      return false;
}

在 Java SE 中,我可以使用 ServiceLoader:在企业环境中,如何找到所有实现类并在运行时决定在合适的情况下使用它的实现? 谢谢!

【问题讨论】:

    标签: java jakarta-ee ejb cdi


    【解决方案1】:

    我可以想到几种使用 CDI 解决此问题的方法。

    首先,如果isSuitableFor 方法与您列出的一样简单,您可以将Qualifier@Nonbinding 值一起用于列出的int,然后只需查找具有该限定符值的实现即可。假设限定符是@VerticesTriangle 的值是3,那么限定符变为:

    @Qualifier
    @Target({ TYPE, METHOD, PARAMETER, FIELD })
    @Retention(RUNTIME)
    @Documented
    public @interface Vertices {
        @Nonbinding int value();
    }
    

    三角形变成:

    @Vertices(3)
    public class Triangle implements Polygon{
    }
    

    您可以通过以下方式获得对它的引用:

    @Inject
    @Vertices(3)
    private Polygon polygon;
    

    或者您可以为顶点创建一个AnnotationLiteral 并通过实例手动查找它。

    另一种方法是遍历所有实例,如下所示:

    @Inject
    @Any
    private Instance<Polygon> polygons;
    
    for(Polygon p : polygons) {
        if(p.isSuitableFor(x)) {
            // do something.
        }
    }
    

    这假设所有的多边形都是注册的 bean。对于大量多边形,这会很慢。

    第三种方法是使用事件,而不是限定类,而是限定观察者方法。例如

    @Inject
    private Event<SomePayload> somePayload;
    
    
    // later on
    somePayload.select(new VerticesLiteral(3)).fire(somePayload);
    
    // and the observer method in Triangle
    public void handle(@Observes @Vertices(3) SomePayload somePayload) { ... }
    
    // and in square
    public void handle(@Observes @Vertices(4) SomePayload somePayload) { ... }
    

    【讨论】:

      猜你喜欢
      • 2023-03-28
      • 2012-07-07
      • 2016-08-30
      • 2012-08-07
      • 1970-01-01
      • 1970-01-01
      • 2017-03-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多