2013-03-08 24 views
5

Tôi đang chạy vào một vấn đề với CDI tiêm vào một container Weld trong JBoss 7.1.1CDI loop tiêm

Tôi đã có mô hình đối tượng sau đây:

@Stateless 
class ServiceEjb { 
@Inject 
A a; 
} 

class A { 
@Inject 
B b; 
} 

class B { 
@Inject 
A a; 
} 

Khi cố gắng tiêm Một hoặc B trong lớp không trạng thái của tôi, vòng lặp tiêm và sự cố với javax.enterprise.inject.CreationException.

Tôi thử nhiều thứ (phạm vi, @Singleton trên A hoặc B nhưng không thành công). Tôi không muốn phá vỡ mã, và những mũi tiêm đó tạo ra các giác quan.

Mọi đầu mối sẽ được đánh giá cao.

Trả lời

10

Circular dependency injection is not required by the CDI standard, trừ khi ít nhất một hạt trong chu kỳ có normal scope. Giải pháp đơn giản nhất là cung cấp cho A hoặc B một phạm vi bình thường. Nếu bạn không thể đưa ra một phạm vi bình thường (từ mã giả lập, có vẻ như tất cả chúng đều có phạm vi giả mặc định là @Dependent), bạn sẽ phải tìm các giải pháp khác. Đăng một mẫu mã thực có thể cho phép chúng tôi giúp bạn với một giải pháp cụ thể, nhưng đây là một sự khởi đầu:

  • A và B có thể kết hợp vào cùng một lớp không?
  • Một lớp mới, C, có thể được trích xuất từ ​​A và B, sao cho cả A và B @Inject C thay vì nhau?

Dưới đây là một số SO liên kết với các giải pháp khác mà bạn có thể thấy hữu ích:

MVP with CDI; avoiding circular dependency

https://stackoverflow.com/questions/14044538/how-to-avoid-cdi-circular-dependency

+0

Thank cho trả lời nhanh chóng của bạn. Tôi phải thừa nhận rằng khái niệm về phạm vi bình thường không phải là rất rõ ràng đối với tôi. Các liên kết bạn cung cấp nói về @NormalScope nhưng điều này không tồn tại. Làm thế nào để khai báo một phạm vi bình thường? – jmcollin92

+0

[Hầu hết các phạm vi đều là phạm vi bình thường.] (Http://docs.jboss.org/cdi/spec/1.0/html/contexts.html#normalscope) Phiên, ứng dụng, cuộc trò chuyện và phạm vi yêu cầu là phạm vi bình thường. Điều này trái ngược với _pseudoscopes_: singleton và phụ thuộc (đó là mặc định khi bạn không viết trong chú thích phạm vi). – Nick

+0

Vì vậy, bởi vì tôi đã cố gắng khai báo phạm vi, điều này sẽ làm việc, nếu tôi hiểu rõ. Tôi có thể thử loại phạm vi nào với DAO (truy cập bởi một SessionBean)? – jmcollin92

4

tôi giải quyết vấn đề bằng cách sử dụng javax.inject.Provider một cách rõ ràng. Mặc dù tôi cảm thấy như thế này nên được thực hiện dưới mui xe của WELD tự động điều này cũng không phải là trường hợp của tôi. Điều này làm việc cho tôi và giải quyết vấn đề liên quan của tôi.

class A { 
    @Inject 
    Provider<B> b; // access with b.get() 
} 

class B { 
    @Inject 
    Provider<A> a; // access with a.get() 
} 

Tôi chưa thử nghiệm, nhưng có thể đủ để sử dụng một Nhà cung cấp để phá vỡ chu kỳ, tức là bạn không cần sử dụng nó trong cả hai lớp.

1

Bạn nên tiêm một Instance <B> thay vì B (và/hoặc thẩm < Một > thay vì A)