Tôi mới sử dụng Google Guice và hiểu Dependency Injection một cách khái niệm, nhưng tôi đang gặp phải các vấn đề đang cố gắng kết hợp nó vào ứng dụng của mình. Câu hỏi cụ thể của tôi là về các vật thể Singleton. Dưới đây là ví dụ:Guice Singleton Static Injection Pattern
Đầu tiên, lớp Mô-đun của tôi, liên kết với giao diện Singleton Connection nặng để triển khai.
public class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(Connection.class).to(MyConnection.class).asEagerSingleton();
}
}
Bây giờ, trong phương pháp chính của tôi, tôi nhanh chóng máy chủ ứng dụng của tôi và tiêm Connection:
public class MyApplication {
@Inject
public MyApplication(Connection cxn) {
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(new MyModule());
MyApplication app = injector.getInstance(MyApplication.class);
// Start application, add ShutdownHook, etc...
}
}
Tất cả những gì tốt cho đến nay ... Bây giờ, tôi có một số lớp DAO mà tận dụng đối tượng Connection của tôi , nhưng được lấy ra bằng các phương pháp tĩnh như vậy:
public class MyConfiguration {
private Config conf;
private Connection cxn; // Would like to have this injected
private MyConfiguration(Config conf) {
this.conf = conf;
}
public static MyConfiguration getConfig(String name) {
return new MyConfiguration(cxn.getConfig(name));
}
}
giả định đầu tiên của tôi là tôi chỉ đơn giản là sẽ thêm @Inject
để cxn
nhưng điều này không w ork bởi vì tôi không nhận được ví dụ từ Guice; nó chỉ cho tôi một NPE. Con đường tôi nhìn thấy nó, tôi có 2 lựa chọn để khai thác đối tượng Connection:
- Expose một phương pháp
getConnection()
trong MyApplication cơ bản sau Service Locator Pattern - Thêm
requestStaticInjection(MyConfiguration)
đểMyModule
tôi chọn cho # 2 , tuy nhiên, docs say:
API này không được khuyến nghị sử dụng chung
Thực hành tốt nhất để cung cấp Singleton cho các lớp học cần có mà không cần phải trải qua Injector.getInstance
mỗi lần? Tôi đang thiếu gì?
Bạn nói điều đó cho mình, thay đổi phương thức để có không tĩnh;) – alfasin
Tôi đồng ý với @alfasin lý do bạn mất một trong những lý do chính để làm DI nếu bạn có các cuộc gọi tĩnh mà không thể được tiêm khác nhau. Tại sao bạn không sử dụng một mẫu đơn DI không cho MyConfiguration? – JasonOfEarth
Ví dụ của tôi có phần bị giải thích. Trong ứng dụng của tôi, "Cấu hình" thực sự là một kết nối cơ sở dữ liệu đồ thị. Cxn.getConfig thực sự là một quá trình truyền tải đồ thị tìm thấy một nút có tên đã cho. Đối tượng MyConfiguration là một trình bao bọc xung quanh nút này cung cấp thông tin tên miền cụ thể. Tôi dự định sử dụng nó theo cách thông thạo: MyConfiguration.getConfig ("x"). GetName(), v.v. Hãy nói rằng tôi đã loại bỏ đối tượng tĩnh instantiation, tôi sẽ phải sử dụng Injector.getInstance trên tất cả các mã của tôi bất cứ khi nào tôi cần một ? Làm thế nào để xử lý các tham số constructor mà không nên được tiêm? – lamarvannoy