我只将 OSGi 与 Karaf 一起使用,因此对于其他环境可能会有所不同。
如果您需要为每个配置文件提供 OSGi 服务,您可以使用声明性服务注释设置此类服务,例如这样。
import org.osgi.framework.BundleContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ConfigurationPolicy;
import org.osgi.service.metatype.annotations.Designate;
import com.example.service.config.ExampleServiceConfig;
@Component(
immediate = true, service = ExampleService.class,
configurationPolicy = ConfigurationPolicy.REQUIRE,
configurationPid = "com.example.service.ExampleService"
)
@Designate(ocd = ExampleServiceConfig.class, factory = true)
public class ExampleService {
@Activate
public void onServiceActivate(BundleContext context, ExampleServiceConfig config){
System.out.println(config.hello_message());
}
}
然后为服务定义类型安全的配置,例如:
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
@ObjectClassDefinition(name = "ExampleService Configuration")
public @interface ExampleServiceConfig {
String hello_message() default "hello world";
String osgi_jndi_service_name() default "unique.service.name";
}
由于单例配置使用<configurationPid>.cfg 之类的文件名,工厂配置使用<configurationPid>-<InstanceName>.cfg 格式,因此要在上面创建ExampleService 的两个实例,您可以创建例如以下配置:
com.example.service.ExampleService-InstanceA.cfg
hello.message=Hello from Instance A
osgi.jdni.service.name=InstanceA
com.example.service.ExampleService-InstanceB.cfg
hello.message=Hello from Instance B
osgi.jdni.service.name=InstanceB
至少在 Karaf 中,这将创建两个 ExampleService 实例和两个具有某种唯一 guid(而不是实例名称)的配置。要引用特定的服务实例,您可以使用引用注释中的目标属性。
@Reference(
target = "(osgi.jdni.service.name=InstanceA)"
)
ExampleService exampleService;