方法访问和非导出包

时间:2017-05-20 12:51:27

标签: java osgi

我有一个包含两个包的OSGi包:

  1. com.organization.api导出此包。
  2. com.organization.internal此包未导出。
  3. 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中解决这个问题?

2 个答案:

答案 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的情况下更新管理器实现,可能会有一些额外的复杂情况,但这似乎不是必需的。