gpt4 book ai didi

java - OSGI包可见服务实现

转载 作者:行者123 更新时间:2023-12-02 04:14:18 26 4
gpt4 key购买 nike

我想用 OSGI 来完成一些事情,这在 Guice 或 Spring 等依赖注入(inject)框架中非常简单。

我想将服务实现类与服务接口(interface)放在同一个包中。这使我能够使用服务客户端不关心的包可见方法。

Guice 实现这一点的方法很简单,让服务实现类包可见。服务接口(interface):

package com.example.services;

public interface SomeService {

void scanClasses(ServiceHelper helper);
}

以及实现:

package com.example.services;

// Package visible service implementation
class SomeServiceImpl implements SomeService {

@Override
public void scanClasses(ServiceHelper helper) {
ClassLoader bundlesClassLoader = helper.getClassLoader();
// do something with bundle's classes
}

}

这是 ServiceHelper 类,它也具有包可见的方法:

package com.example.services;

import org.osgi.framework.BundleContext;
import org.osgi.framework.wiring.BundleWiring;

public class ServiceHelper {
private ClassLoader bundleClassLoader;

public ServiceHelper(BundleContext bc) {
this.bundleClassLoader = bc.getBundle().adapt(BundleWiring.class).getClassLoader();
}

// Package visible method to be called from SomeServiceImpl class
ClassLoader getClassLoader() {
return bundleClassLoader;
}

}

但是OSGI无法使用包可见的声明或构造函数实例化ServiceImpl类:

java.lang.IllegalAccessException: Class org.eclipse.equinox.internal.ds.model.ServiceComponent can not access a member of class com.example.SomeServiceImpl with modifiers ""

为了完成示例,这是服务客户端代码,不应受到设计的影响:

package com.example.serviceclient;

import org.osgi.framework.BundleContext;

import com.example.services.ServiceHelper;
import com.example.services.SomeService;

public class ServiceClientExample {

private SomeService someService;

public void activate(BundleContext bc) {
someService.scanClasses(new ServiceHelper(bc));
}

public void setSomeService(SomeService service) {
this.someService = service;
}
}

将服务实现放入另一个包中,并尝试构建良好的面向对象封装需要太多工作,例如将包可见方法映射到调用者的访问器类,我相信应该有另一种方法。

最佳答案

您正在使用 OSGi 声明性服务,它确实要求实现类是公共(public)的,并且具有公共(public)的零参数构造函数。这是设计使然。您可以通过使用 BundleActivator 并在代码中实例化组件来解决此问题,但是没有什么意义......

如果您的实现类与接口(interface)位于同一包中,则接口(interface)的每个客户端都直接耦合到实现类。所以你不妨将实现类公开并允许客户端直接实例化它。

OSGi 允许合约、提供者和消费者真正分离。将合约和提供者耦合到同一个包中可以解决这个问题。事实上,Guice 和 Spring 能够“直接”地将这些概念结合在一起。

关于java - OSGI包可见服务实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33473670/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com