Java Enterprise中的服务提供程序接口

时间:2014-05-26 23:37:17

标签: java java-ee ejb cdi

我想通过使用服务提供程序接口来编写一个非常模块化的工厂,因此无需每次都修改工厂本身。

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

示例:我有一个interface Poligon
和具体的Class Triangle implements Poligon。判别方法是:

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

在Java SE中我可以使用ServiceLoader来完成它:在企业环境中如何找到所有实现类,并在运行时决定使用它的实现,如果合适的话? THX!

1 个答案:

答案 0 :(得分:1)

我可以考虑使用CDI解决这个问题。

首先,如果isSuitableFor方法与列表一样简单,则可以对列出的int使用Qualifier @Nonbinding值,并使用该方法查找实现限定符值。假设限定符为@VerticesTriangle的值为3,那么限定符将变为:

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

而Triangle成为:

@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。对于大量多边形,这将是缓慢的。

第三种方法是使用一个事件,而不是限定类,限定观察者方法。 E.g。

@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) { ... }