Java 如何从库中提供组件供多个DI框架使用

Java 如何从库中提供组件供多个DI框架使用,java,spring,dependency-injection,guice,Java,Spring,Dependency Injection,Guice,我的团队拥有一个库,该库提供的组件必须由使用该库的代码引用。我们的一些消费者使用Spring来实例化他们的应用程序;其他人使用Guice。我们希望得到一些关于如何提供这些组件的最佳实践的反馈。目前有两种选择: 让我们的库提供一个Spring配置,消费者可以@导入,以及一个Guice模块,他们可以安装 让我们的库提供一个ComponentProvidersingleton,它提供获取库提供的相关组件的方法 快速绘制这些外观的草图: 在这两种方法中都存在 //在他们的代码中 @AllArgsCons

我的团队拥有一个库,该库提供的组件必须由使用该库的代码引用。我们的一些消费者使用Spring来实例化他们的应用程序;其他人使用Guice。我们希望得到一些关于如何提供这些组件的最佳实践的反馈。目前有两种选择:

  • 让我们的库提供一个Spring
    配置
    ,消费者可以
    @导入
    ,以及一个Guice
    模块
    ,他们可以
    安装
  • 让我们的库提供一个
    ComponentProvider
    singleton,它提供获取库提供的相关组件的方法
  • 快速绘制这些外观的草图:

    在这两种方法中都存在
    //在他们的代码中
    @AllArgsConstructor(onConstructor=@_uu(@Inject))
    公共类消费类{
    私人终审法院;
    ...
    }
    
    第一种方法
    //在我们的代码中
    @配置
    公共类库配置{
    @Bean public foo依赖项foo(){…}
    ...
    }
    ---
    公共类LibraryModule扩展了AbstractModule{
    @提供FooDependency foo(){…}
    ...
    }
    ========================
    ========================
    //在他们的代码中
    @配置
    @导入(LibraryConfiguration.java)
    公共类使用者配置{
    //不管他们想要什么样的启动逻辑——但关键是,他们确实需要
    //*不*需要定义FoodDependency
    ...
    }
    ---
    //*或*
    公共类ConsumerModule扩展了AbstractModule{
    @凌驾
    public void configure(){
    //或者,在创建喷油器时只需指定LibraryModule
    安装(新的LibraryModule());
    ...
    //如上所述,不需要定义FoodDependency
    }
    }
    
    第二种方法
    //在我们的代码中
    公共类库提供者{
    公共静态最终实例=buildInstance();
    私有静态库提供程序buildInstance(){…}
    私有静态库提供程序getInstance(){return INSTANCE;}
    }
    ========================
    ========================
    //在他们的代码中
    @配置
    公共类使用者配置{
    @豆豉{
    返回LibraryProvider.getInstance().getFoo();
    }
    ...
    }
    //或Guice的同等产品
    

    对于这种情况,是否有公认的最佳实践?如果不是的话,每种方法或我还没有想到的另一种方法的利弊是什么?第一种方法的优点是使用者不需要编写任何代码来初始化依赖项,DI框架可以覆盖依赖项(例如,使用模拟依赖项进行测试);第二种方法的优点是不依赖DI框架(例如,如果新消费者想使用Dagger来实例化他们的应用程序,我们根本不需要更改库)

    我认为第一种方法更好。如果您的库在bean之间有相互依赖关系,那么
    @Configuration
    的代码(在第二种方法中是spring)将是:

  • 易碎(如果应用程序不知道应该创建某个bean怎么办)
  • 重复-此代码将出现在每个消费者模块中
  • 当您的库的新版本发布并且消费者想要升级时,消费者的配置可能会发生变化(库可能会公开一个新bean、弃用甚至删除一些旧内容,等等)
  • 一个小建议:

    您可以使用Spring工厂,在Spring引导的情况下甚至不需要进行
    @Import
    。只需添加一个maven依赖项,它就会自动加载配置

    现在,确保在使用这种方法时正确处理依赖项。
    因为您的代码将同时包含spring和Juice相关的代码,所以您将为库的maven/gradle模块添加对这两种代码的依赖。这意味着,使用guice的消费者将因为您的库而获得所有spring内容。根据您选择的构建系统,有很多方法可以解决此问题,只想提出它

    感谢您的回复,谢谢!我们实际上使用的是一个内部构建系统,因此“maven依赖项”并不相关——但我们将研究Spring工厂,以建议消费者如何消费。至于我们的消费者在依赖我们时同时获得Spring和Guice依赖,请注意,谢谢,但是我们的构建系统有办法排除不必要的依赖,所以应该有办法解决。