簡體   English   中英

Java 依賴注入的模塊化

[英]Java Modularity with Dependency Injection

讓我們假設一個基於OpenJDK 11 + OpenJFX 11的應用程序。 代碼庫組織在單個 java 模塊中(請參閱Java 9 模塊化指南以供參考)。

到目前為止,我將所有基於JavaFX的項目與 Google 的依賴注入框架Guice結合在一起。 對於模塊化項目,這似乎不起作用......

SQLiteCompassApplication.java

public class SQLiteCompassApplication extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    public void start(Stage stage) throws Exception {

         Injector injector = Guice.createInjector(new MyModule());

         FXMLLoader fxmlLoader = injector.getInstance(FXMLLoader.class);

         try(InputStream fxmlStream = getClass().getResourceAsStream("/view/View.fxml")) {

            Parent root = fxmlLoader.load(fxmlStream);
            stage.setScene(new Scene(root));
            stage.setTitle("SQLite Compass");
            stage.setOnCloseRequest(event -> System.exit(0));
            stage.show();
        }
    }
}

模塊信息.java

module org.x1c1b.sqlitecompass {

    requires javafx.controls;
    requires javafx.fxml;
    requires com.google.guice;

    exports org.x1c1b.sqlitecompass;
}

為了簡單起見, Guice配置,這意味着聲明的Guice模塊(不要與 java 模塊混淆)沒有粘貼,但仍然適用於非模塊化項目。

執行此代碼時,我收到以下異常:

Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field com.google.inject.Injector org.x1c1b.sqlitecompass.config.provider.FXMLLoaderProvider.injector accessible: module org.x1c1b.sqlitecompass does not "opens org.x1c1b.sqlitecompass.config.provider" to module com.google.guice
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:340)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:280)
    at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:176)
    at java.base/java.lang.reflect.Field.setAccessible(Field.java:170)
    at com.google.guice@4.2.2/com.google.inject.internal.SingleFieldInjector.<init>(SingleFieldInjector.java:38)
    at com.google.guice@4.2.2/com.google.inject.internal.MembersInjectorStore.getInjectors(MembersInjectorStore.java:126)
    at com.google.guice@4.2.2/com.google.inject.internal.MembersInjectorStore.createWithListeners(MembersInjectorStore.java:93)
    at com.google.guice@4.2.2/com.google.inject.internal.MembersInjectorStore.access$000(MembersInjectorStore.java:36)
    at com.google.guice@4.2.2/com.google.inject.internal.MembersInjectorStore$1.create(MembersInjectorStore.java:45)
    at com.google.guice@4.2.2/com.google.inject.internal.MembersInjectorStore$1.create(MembersInjectorStore.java:41)
    at com.google.guice@4.2.2/com.google.inject.internal.FailableCache$1.load(FailableCache.java:40)
    at com.google.common@25.1-android/com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3444)
    at com.google.common@25.1-android/com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2193)
    at com.google.common@25.1-android/com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2152)
    at com.google.common@25.1-android/com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2042)
    ... 39 more
Exception running application org.x1c1b.sqlitecompass.SQLiteCompassApplication

我可以通過粘貼opens org.x1c1b.sqlitecompass.config.provider; module-info.java 但這會導致更多例外情況......

我應該如何配置我的模塊module-info.java以將其與Google Guice一起使用? 是否可以結合使用Google Guice模塊化

編輯

當我更改以下幾行時,它似乎有效:

  • 添加exports org.x1c1b.sqlitecompass.config ,其中我的Guice模塊被聲明,到module-info.java
  • 使用附加 VM 選項執行程序--add-opens java.base/java.lang=com.google.guice

但我想這更多的是在這里找到的解決方法,而不是官方解決方案......

您必須打開所有將通過 Guice 反射訪問的包。 最簡單的方法是通過在module-info.java這個詞放在module前面來聲明整個模塊為open

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM