我有一个包含两个包的OSGi包:
com.organization.api
导出此包。com.organization.internal
此包未导出。在com.organization.api
我有一个界面Foo
和一个等级AsbtractFoo
package com.organization.api;
public abstract class AbstractFoo implements Foo {
private int state;
@Override
public int getState(){
return this.state;
}
}
在com.organization.internal
我有一个类FooManager
需要改变Foo的状态。如何处理com.organization.internal
之外的任何其他类不能改变foo状态的条件。
package com.organization.internal;
public class FooManager {
private ???? foo = ....
public void updateFooState(){
foo.????();
}
}
我尝试将AbstractStatefullFoo
设置为默认访问权限void setState(int state)
)添加到com.organization.internal
包,并使AbstractFoo
扩展AbstractStatefullFoo
,但问题是这个案例其他捆绑包需要导出包com.organization.internal
。
如何在OSGi中解决这个问题?
答案 0 :(得分:1)
我觉得你想要与所有那些抽象类复杂化。
最简单的情况是使用getState接口Foo。 然后,您在内部包中有一个Foo实现。
此案例不要求其他bundle可以访问internal中的impl类。关键是在api包中还有一个FooManager接口。
然后创建实现FooManager的FooManagerImpl并将其作为带有接口的服务导出。然后,其他bundle可以使用此服务来调用updateState()方法和其他操作FooImpl类的方法。
答案 1 :(得分:0)
扩展上一个答案。
如果您封装了可变的foo状态,并将工厂公开为服务,那么可能会为您简化的事情就是。将foo manager服务作为工厂可能是明智的,以确保它们保持同步。
FooState实现可以提供更改状态的方法,这些方法不包含在接口中,而且是实现包的私有状态。应将FooState接口标记为不用于Consumer实现。
可以更改Foo界面以允许访问FooState。此对象是只读的(除非使用反射),但不是正确不可变的。您可以直接将访问方法添加到Foo,也可以创建一个额外的导出接口,以避免使不关心此问题的API用户的界面变得复杂。 AbstractFoo实现可以移动到单独的导出包中。如果默认实现可能会生成受保护的方法并且通常比API本身更快地更改,那么这可能会很好,您不必经常使用API版本。
抽象类可以负责获取FooState以及其他实现支持任务。
如果您需要能够在不更新Foos的情况下更新管理器实现,可能会有一些额外的复杂情况,但这似乎不是必需的。