Tôi đang gặp một số khó khăn khi hiểu được cách thức hoạt động đơn âm của Guice. Tôi đã đọc tài liệu sẵn có (ở đây - http://code.google.com/p/google-guice/wiki/Scopes), nhưng tôi vẫn không thể tìm ra một số thứ:Guice eager/lazy singleton instantiations
1) Tôi đã tích hợp Guice với Tomcat và tôi đã thiết lập một số ràng buộc trong ServletModule:
bind(MyServlet.class).asEagerSingleton();
serve("myUrl").with(MyServlet.class);
serve("myOtherUrl").with(MyOtherServlet.class);
(nơi lớp MyOtherServlet có một chú thích @Singleton trên nó) My Mục đích ở đây là để có hai servlets, nơi người ta đang háo hức khởi tạo, trong khi người kia thì không. Tuy nhiên có vẻ như dòng "serve ... with ..." tự động khởi tạo các đối tượng servlet, mặc dù lớp đó không bị ràng buộc như một singleton mong muốn. Các liên kết tôi đính kèm ở trên đề cập đến sự khác biệt giữa Guice chạy dưới Stage.Development và Stage.Production - tuy nhiên điều này vẫn xảy ra ngay cả khi tôi sử dụng rõ ràng Stage.Development (đó là mặc định một anyway). Có cách nào để tránh điều này không?
2) (tiếp tục 1) Cố gắng đảm bảo rằng MyServlet được khởi tạo ngay trước khi tất cả servlet khởi tạo háo hức ngay bây giờ, tôi đã sửa đổi thứ tự của mô-đun (và câu lệnh ràng buộc) khi tạo Injector, để ràng buộc cho MyServlet xuất hiện đầu tiên. Tuy nhiên, tôi thấy rằng nó vẫn được instantiated muộn hơn một số ràng buộc khác (các lớp phi servlet), trong đó đã có dạng:
bind(MyInterface.class).to(MyClass.class).asEagerSingleton()
mặc dù những cam kết ràng buộc khác xuất hiện sau này trong các module/bindings trật tự. Tôi đã xem xét nó, và thấy rằng Guice đơn giản là tạo ra các trình đơn mong muốn bị ràng buộc bởi dạng "bind ... to ... asEagerSingleton()" trước khi nó thực hiện "bind" asEagerSingleton() " và vì vậy tôi đã giải quyết nó bằng cách sửa đổi dòng: bind (MyServlet.class) .asEagerSingleton(); vào: liên kết (MyServletDummyInterface.class) .to (MyServlet.class) .asEagerSingleton()
và thực tế đã hoạt động. Tuy nhiên, tôi muốn tránh có một giao diện giả chỉ để giải quyết điều này, vì vậy tôi đã tự hỏi nếu có ai có một giải pháp tốt hơn cho điều này ..?
3) Tôi có hai mô-đun Guice - một ServletModule và một AbstractModule. Các configureServlets ServletModule() đã sau ràng buộc trong đó:
serve("aUrl").with(SomeServlet.class);
cấu hình của AbstractModule() có các ràng buộc sau:
bind(SomeImpl.class).asEagerSingleton();
bind(SomeInterface.class).to(SomeImpl.class).in(Singleton.class);
Bên cạnh đó, Lớp SomeServlet có một lĩnh vực tiêm loại SomeInterface, và có chú thích @Singleton ở đầu lớp.
Bây giờ, người ta có thể mong đợi rằng khi tạo một bộ phun, lớp SomeImpl sẽ được khởi tạo, và cùng một cá thể sẽ được đưa vào thể hiện SomeServlet. Như đã đề cập trước đây, servlets bị ràng buộc với câu lệnh "serve ... with ..." cũng dường như được khởi tạo một cách hăng hái, nhưng dù cách nào thì vẫn chỉ có một đối tượng SomeImpl được khởi tạo. Tuy nhiên, vì một lý do nào đó, tôi có hai đối tượng SomeImpl được khởi tạo khi thực hiện điều này. Để có được xung quanh nó, tôi trộn hai dòng trong configure() một chút, và thay vào đó những điều trên tôi đã có những dòng sau:
bind(SomeImpl.class).in(Singleton.class)
bind(SomeInterface.class).to(SomeImpl.class).asEagerSingleton();
và sau đó nó làm việc tốt, và tôi đã nhận chỉ có một thể hiện của SomeImpl đã khởi tạo.Tôi không thực sự hiểu tại sao switch lại quan trọng - tôi có thể thấy cách thứ hai là "tốt hơn", nhưng tôi hy vọng cả hai sẽ hoạt động chính xác, vì vậy tôi chỉ tự hỏi liệu tôi có gặp vấn đề gì ở đây không .. ?
Xin lỗi về độ dài,
Cảm ơn sự trợ giúp!