JavaFX8 - Guice 的线程任务

Mis*_*e83 1 java multithreading guice javafx-8

我是 Guice 和 JavaFX 的新手(非常新)。我正在构建一个应用程序,它有一个线程侦听套接字连接,并且在接收到事件后,线程将值存储在 ObservableArrayList() 上,应用程序会将它们通知给用户。

我的问题是如何构建所有这些行为,以及如何从线程和 JavaFX 控制器“共享” ObservableList。

我正在阅读有关 Guice 的文章,它可以帮助解耦new对象的创建。

我试图设置一些东西,但 @Inject 属性在我的可运行任务中为空:

图形模块:

public class AppGuiceModule extends AbstractModule{

    @Override
    protected void configure() {
        bind(EventsDAO.class).toInstance(new EventsDAO());
    }

}
Run Code Online (Sandbox Code Playgroud)

EventsDAO(具有 ObservableArrayList )

@Singleton
public class EventsDAO {
     private ObservableList<ScheduledEvent> localCache = FXCollections.observableArrayList();

     public void addEvent(ScheduledEvent event) {
         localCache.add(event);
     }

     public void removeEvent(ScheduledEvent event) {
         this.localCache.remove(event);
     }
}
Run Code Online (Sandbox Code Playgroud)

有了两个这个,我在我的主要我去创建注入器:

@Override
    public void start(Stage stage) throws Exception {

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

        Platform.setImplicitExit(false);

        Thread t = new Thread(new EventsReceiverTask());
        t.start();
        .....
Run Code Online (Sandbox Code Playgroud)

现在,在 Runnable 对象中,我会在我的控制器中 @Inject EventsDAO(以保存新事件)和 @Inject 这个,向 localCache 添加一个侦听器(是的 localCache 是私有的,我将提供一个 getter)。

可运行对象:

public class EventsReceiverTask implements Runnable {

    private static final int port = 4020;

    @Inject
    EventsDAO eventsDao; // This is null, why not injected ?

    private ServerSocket serverSocket;
    private Stage notificationStage;

    public EventsReceiverTask() {
        try {
            this.serverSocket = new ServerSocket(port);
            this.notificationStage = new Stage();

            eventsDao.addEvent(new ScheduledEvent());
        } catch (IOException ex) {
            Logger.getLogger(EventsReceiverTask.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
Run Code Online (Sandbox Code Playgroud)

我不知道这是否是在 JavaFX 中实现“生产者-消费者”的正确方法,但我不知道如何使用所有静态方法共享这些组件,而无需创建乏味的 getter 和 setter。

dur*_*597 5

您的问题确切地说明了为什么在可能的情况下最好不要在依赖注入系统中使用 new

只有当注入框架是创建对象的框架时才会发生注入。当您调用 时new正在创建它们,而不是框架

有两种方法可以让 Guice 为您创建一个对象:

  1. injector.getInstance(Foo.class);

通过控制反转,流程取决于在程序执行期间建立的对象图。通过抽象定义的对象交互使这种动态流成为可能。

  1. 让 Guice 为您创建对象作为注入。
    • 这正是@Inject注释所做的;指示 Guice 在绑定的类中为您创建对象。

一般来说,名称为 like 的EventsReceiverTask类不是您想要在main方法中创建的顶级类。它们的名称更像是EventService,您可以向其中注入一个Provider<EventsReceiverTask>能够为您创建新任务的名称,所有这些都将EventsDAO正确地注入您的。


旁注:你没有问这个,但是当你这样做时,在你的模块中:

bind(EventsDAO.class).toInstance(new EventsDAO());
Run Code Online (Sandbox Code Playgroud)

您正在覆盖您尝试使用@Singleton类定义中的注释指定的绑定范围。如果你希望这个对象实际上是一个单例,你 ** 还必须@Singleton在你的模块中指定绑定,例如

bind(EventsDAO.class).toInstance(new EventsDAO()).in(Singleton.class);
Run Code Online (Sandbox Code Playgroud)

从文档:

如果类型和语句中的范围存在冲突bind(),则将使用bind()语句的范围。如果类型用您不想要的范围进行注释,请将其绑定到Scopes.NO_SCOPE.