当前页面: 开发资料首页 → Eclipse 专题 → 在Eclipse RCP中实现反转控制(IoC)
摘要: Eclipse富客户平台(RCP)是一个功能强大的软件平台,它基于插件间的互连与协作,允许开发人员构建通用的应用程序。
@Injected public void aServicingMethod(Service s1, AnotherService s2) {
// 将s1和s2保存到类变量,需要时可以使用
} 反转控制容器将查找Injected注释,使用请求的参数调用该方法。我们想将IoC引入Eclipse平台,服务和可服务对象将打包放入Eclipse插件中。插件定义一个扩展点 (名称为com.onjava.servicelocator.servicefactory),它可以向程序提供服务工厂。当可服务对象需要配置时,插件向一个工厂请求一个服务实例。ServiceLocator类将完成所有的工作,下面的代码描述该类(我们省略了分析扩展点的部分,因为它比较直观):
/**
* Injects the requested dependencies into the parameter object. It scans
* the serviceable object looking for methods tagged with the
* {@link Injected} annotation.Parameter types are extracted from the
* matching method. An instance of each type is created from the registered
* factories (see {@link IServiceFactory}). When instances for all the
* parameter types have been created the method is invoked and the next one
* is examined.
*
* @param serviceable
* the object to be serviced
* @throws ServiceException
*/
public static void service(Object serviceable) throws ServiceException {
ServiceLocator sl = getInstance();
if (sl.isAlreadyServiced(serviceable)) {
// prevent multiple initializations due to
// constructor hierarchies
System.out.println("Object " + serviceable
+ " has already been configured ");
return;
}
System.out.println("Configuring " + serviceable);
// Parse the class for the requested services
for (Method m : serviceable.getClass().getMethods()) {
boolean skip = false;
Injected ann = m.getAnnotation(Injected.class);
if (ann != null) {
Object[] services = new Object[m.getParameterTypes().length];
int i = 0;
for (Class<?> class : m.getParameterTypes()) {
IServiceFactory factory = sl.getFactory(class, ann
.optional());
if (factory == null) {
skip = true;
break;
}
Object service = factory.getServiceInstance();
// sanity check: verify that the returned
// service's class is the expected one
// from the method
assert (service.getClass().equals(class) || class
.isAssignableFrom(service.getClass()));
services[i++] = service;
}
try {
if (!skip)
m.invoke(serviceable, services);
} catch (IllegalAccessException iae) {
if (!ann.optional())
throw new ServiceException(
"Unable to initialize services on "
+ serviceable + ": " + iae.getMessage(), iae);
} catch (InvocationTargetException ite) {
if (!ann.optional())
throw new ServiceException(
"Unable to initialize services on "
+ serviceable + ": " + ite.getMessage(), ite);
}
}
}
sl.setAsServiced(serviceable);
}