Tôi mới đến khái niệm này, nhưng đây là sự hiểu biết của tôi.
Giả sử bạn có giao diện A
và B
và triển khai Ai
và Bi
.
Nếu Ai
có một sự phụ thuộc vào B
, và Bi
có một sự phụ thuộc vào A
, sau đó Guice có thể tạo ra một thực proxy của A
(gọi nó là Ap
) sẽ tại một số điểm trong tương lai được đưa ra một Ai
để uỷ thác cho. Guice cho rằng Ap
đến Bi
cho sự phụ thuộc của nó trên A
, cho phép Bi
hoàn thành việc khởi tạo. Sau đó, kể từ khi Bi
được khởi tạo, Guice có thể khởi tạo Ai
với Bi
. Sau đó, kể từ khi Ai
hiện hữu ích, Guice yêu cầu Ap
ủy quyền cho Ai
.
Nếu A
và B
không giao diện (và bạn chỉ có Ai
và Bi
) này chỉ sẽ không được tốt, vì tạo Ap
sẽ yêu cầu bạn mở rộng Ai
, mà đã cần một Bi
.
Đây là những gì nó có thể trông giống như với mã:
public interface A {
void doA();
}
public interface B {
void doB();
}
public class Ai implements A {
private final B b;
@Inject
public Ai(B b) {
this.b = b;
}
public void doA() {
b.doB();
}
}
public class Bi implements B {
private final A a;
@Inject
public Bi(A a) {
this.a = a;
}
public void doB() {
}
}
Proxy lớp Guice làm sẽ trông như thế này:
public class Ap implements A {
private A delegate;
void setDelegate(A a) {
delegate = a;
}
public void doA() {
delegate.doA();
}
}
Và tất cả sẽ được dây sử dụng ý tưởng cơ bản này:
Ap proxyA = new Ap();
B b = new B(proxyA);
A a = new A(b);
proxyA.setDelegate(a);
Và đây là điều sẽ xảy ra nếu bạn chỉ có Ai
và Bi
, không có giao diện A
và B
.
public class Ap extends Ai {
private Ai delegate;
public Ap() {
super(_); //a B is required here, but we can't give one!
}
}
Nếu tôi chỉ ném đủ các lớp học đằng sau giao diện, tất cả mọi thứ sẽ ổn thôi?
Tôi đoán rằng có những hạn chế nghiêm ngặt về cách proxy có thể tương tác với trong hàm tạo. Nói cách khác, nếu B cố gắng gọi A trước khi Guice có cơ hội để điền proxy của A với A thực, thì tôi sẽ mong đợi một RuntimeException.
Tôi cũng thích cách tiếp cận này. Nó có nghĩa là bạn không cần phải tạo giao diện khi bạn không cần chúng. Nó cũng nhanh hơn/ít có khả năng lộn xộn để thay đổi tiêm cho một nhà cung cấp hơn là tạo giao diện. – specialtrevor
Làm cách nào để có sự phụ thuộc rõ ràng vào 'Guice' trong mã ứng dụng của bạn? Tôi đã luôn luôn nghĩ rằng nó là tốt đẹp để ở độc lập của DI framework. Trước khi bạn giới thiệu 'Nhà cung cấp' cho mã của bạn, bạn có thể đã chuyển sang nói' Spring' nhưng điều này là không thể được nữa. –
Tôi đang nói về javax.inject.Provider, một giao diện chuẩn JSR330. Không yêu cầu phụ thuộc guice. –