Java 如何避免OSGi中的class.forName()?

Java 如何避免OSGi中的class.forName()?,java,reflection,osgi,Java,Reflection,Osgi,我对OSGi比较陌生,我们部门正在转向OSGi框架。我有两个包A和B。B依赖于A,所以我将其作为导入包A包含在B的清单文件中 另外,我在a中有一个类,它使用反射从B访问某个类。 A中的类使用Class.forName(B中的类)。我想摆脱这种反射,因为当我转向OSGi框架时,这可能会导致问题。如何摆脱这个类。forName() 谢谢 在我看来,在Java中创建对象有两种方法 通过new调用构造函数 使用反射 所以,若你们想避免反射,你们只能导入bundle A中的类,然后是new()实例(为了做

我对OSGi比较陌生,我们部门正在转向OSGi框架。我有两个包A和B。B依赖于A,所以我将其作为导入包A包含在B的清单文件中

另外,我在a中有一个类,它使用反射从B访问某个类。 A中的类使用Class.forName(B中的类)。我想摆脱这种反射,因为当我转向OSGi框架时,这可能会导致问题。如何摆脱这个类。forName()


谢谢

在我看来,在Java中创建对象有两种方法

  • 通过new调用构造函数
  • 使用反射

  • 所以,若你们想避免反射,你们只能导入bundle A中的类,然后是new()实例(为了做到这一点,你们需要在bundle A中改进B)。但由于bundle B已经依赖于A,这将导致OSGi中不允许的交叉依赖。因此,我建议你重构你的类,从bundle A中提取这样的代码,然后转移到bundle B。

    在OSGi中,你会想远离反射,原因在很多其他地方都有描述

    因此,您的情况是bundle
    A
    需要一个类的实例,该类驻留在bundle
    B
    中。对于
    A
    ,为了理解这个实例,我将假设它有一些接口,它将使用这些接口与该实例进行对话。让我们更具体一点

    /Bundle A
      /ThingyInterface.class
    
    /Bundle B
      /ThingyImplementation.class (implements ThingyInterface.class)
    
    这是一种常规模式:一个bundle提供接口,另一个提供实现。现在有两种可能的情况,

    • A
      只需要一份实现副本。在这种情况下,将
      东西注册为服务
    • A
      需要几个实现实例。在这种情况下,在
      a
      中引入
      ThingyFactory
      ,并在
      B
      中创建该工厂的实现,然后将其注册为服务
    在任何情况下,都允许
    B
    执行实际实例化,您不需要从
    A
    B
    ,并且
    B
    不需要反射来实例化对象


    简言之,服务是你的朋友。

    我不知道你的具体使用情况,但听起来你正在制作一些意大利面条。您说过Bundle B依赖于A,但是A必须通过反射从B加载一个类。这意味着A也依赖于B。因为不能有B->A->B,所以需要删除其中一个依赖项


    或者您可能需要另一个bundle C,它包含A和B所共有的任何类。请记住,OSGi可以帮助您创建具有干净接口的模块。如果您发现在使用OSGi时遇到问题,可能是因为某些抽象正在泄漏,或者某些依赖项设计得不好。

    我认为在一个包中提供接口,在另一个包中提供实现不是一个好主意。一般用例是定义接口->在同一个包中实现接口->使用接口提供服务->其他包引用此服务并使用接口调用,这意味着接口的定义在其类路径中。@Ivan Han--为什么不认为在单独的包中定义接口和实现是一个好主意捆?在大多数情况下,我碰巧认为这是一个非常好的主意,甚至可以称之为最佳实践。@Angelo:谢谢!!我将探索服务。我只是想确认一下,一旦我在B中将“ThingyFactory”实现注册为服务,那么我应该能够在捆绑包a中使用它,而不会出现任何问题?是的,这正是服务的意义所在。某个地方一定有一个很好的介绍,但是你总是可以很好地了解为什么服务对你有好处。@Neil,很抱歉,我没有解释清楚,我说的不好的用户案例是在一个捆绑包(捆绑包a)中定义并实现一个接口,然后在另一个捆绑包(捆绑包B)中实现相同的接口.您忘记了最重要的一点,而这恰好是最好的OSGi方式:依赖注入。使用声明性服务和@Angelo所说的分离是一条出路。@Raduk、@Angelo、@Neil,问题来了。以问题中的exmaple为例,两个捆绑包,捆绑包A和捆绑包B。是的,如果捆绑包A想要使用捆绑包B的某些接口,可以使用服务。但是如果我们想要这样做,我们需要将捆绑包B中的包添加到“导入包”中,对吗?这将导致(束A->束B)。但前提是bundle B已经依赖于bundle A,这意味着(bundle B->bundle A),这是一个依赖循环Ithink@Ivan韩——不,服务不会导致依赖循环。服务实现者和服务使用者(通过导入包)都只依赖于服务接口。它们之间没有依赖关系。服务接口通常应该在第三个捆绑包中,该捆绑包只导出纯API。@Neil,我想我们是在同一条线上。我了解OSGi的服务使用场景。我认为提问者的问题是他有一个依赖循环,所以我建议他将这些部分代码提取到另一个包中,就像你提到的第三个包一样,它只导出纯API,这也是我的建议。但是OSGi的服务似乎可以解决这个问题