Java 方法访问和非导出包

Java 方法访问和非导出包,java,osgi,Java,Osgi,我有一个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

我有一个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.????();
       }
    }
    
    我尝试使用默认访问设置程序(
    void setState(int state)
    )添加
    AbstractStatefullFoo
    )打包
    com.organization.internal
    并使
    AbstractFoo
    扩展
    AbstractStatefullFoo
    ,但问题是在这种情况下,其他捆绑包需要导出包
    com.organization.internal


    如何在OSGi中解决这样的问题?

    我感觉您正在考虑将所有这些抽象类复杂化

    最简单的情况是有一个带有getState的接口Foo。 然后在内部包中有一个Foo的实现

    这种情况下,不需要其他bundle在internal中访问impl类。关键的一点是在api包中还要有一个FooManager接口


    然后创建实现FooManager的FooManagerImpl,并将其导出为带有接口的服务。然后,其他bundle可以使用此服务调用updateState()方法和其他操作FooImpl类的方法。

    在前面的答案上展开

    如果封装可变的foo状态,并将工厂作为服务公开,可能会简化工作。将foomanager服务放在工厂中可能是明智的,以确保它们保持同步

    FooState实现可以提供更改状态的方法,这些方法不包括在接口中,并且是实现捆绑包专用的。FooState接口应标记为不用于使用者实现

    可以更改Foo接口以允许访问FooState。此对象是只读的(除非使用反射),但不是完全不可变的。您可以将访问方法直接添加到Foo中,也可以创建一个额外的导出接口,以避免使不关心此问题的API用户的接口复杂化。 AbstractFoo实现可以移动到单独的导出包中。如果默认实现可能会产生受保护的方法,并且通常比API本身变化得更快,那么这就很好了,因为您不必频繁地修改API的版本

    抽象类可以负责获取FooState以及其他实现支持任务


    如果您需要能够在不更新Foos的情况下更新manager实现,那么可能会有一些额外的复杂性,但这似乎不是一项要求

    谢谢你的回答,但我真的需要抽象类,因为它们包含很多实现,这些实现是在其他bundle的具体类中继承的。你也可以通过中间的抽象类来实现。关键是使用OSGi服务,让其他捆绑包只使用api包中的类。