我想通过使用服务提供程序接口来编写一个非常模块化的工厂,因此无需每次都修改工厂本身。
为此,我希望收到实现接口的所有具体类的列表,并在运行时决定通过方法调用使用哪一个,直到我有一个合适的实现者。
示例:我有一个interface Poligon
和具体的Class Triangle implements Poligon
。判别方法是:
boolean isSuitableFor(int i) {
if (i == 3)
return true;
else
return false;
}
在Java SE中我可以使用ServiceLoader来完成它:在企业环境中如何找到所有实现类,并在运行时决定使用它的实现,如果合适的话? THX!
答案 0 :(得分:1)
我可以考虑使用CDI解决这个问题。
首先,如果isSuitableFor
方法与列表一样简单,则可以对列出的int使用Qualifier
@Nonbinding
值,并使用该方法查找实现限定符值。假设限定符为@Vertices
,Triangle
的值为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) { ... }