Tôi có một biểu đồ các hạt đậu mùa xuân tự động lấy nhau. Minh họa đơn giản hóa quá mức:Mùa xuân tạo ra nhiều phiên bản của một singleton?
<context:annotation-config/>
<bean class="Foo"/>
<bean class="Bar"/>
<bean class="Baz"/>
...
public class Foo {
@Autowired Bar bar;
@Autowired Baz baz;
}
public class Bar {
@Autowired Foo foo;
}
public class Baz {
@Autowired Foo foo;
}
Tất cả những hạt này không có phạm vi nào được chỉ định là đơn độc (làm cho chúng không rõ ràng bất kỳ điều gì, tôi đã thử).
Vấn đề là sau khi instantiation của một bối cảnh ứng dụng duy nhất, trường hợp của Bar
và Baz
chứa trường hợp khác nhau của Foo
. Làm sao điều này xảy ra được?
Tôi đã cố gắng tạo công khai không có hàm tạo args cho Foo
và gỡ lỗi đã xác nhận Foo
được tạo nhiều lần. Dấu vết ngăn xếp cho tất cả các sáng tạo này là here.
Tôi cũng đã cố gắng để cho phép debug logging cho mùa xuân, và trong số tất cả các dòng khác, đã nhận như sau:
DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'Foo'
DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'Foo'
DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'Foo'
Tôi hiểu rằng đậu của tôi là tham khảo chéo nhau, nhưng tôi mong chờ Spring framework để tôn trọng phạm vi singleton và khởi tạo một hạt đơn một lần, và sau đó autowire nó cho bất cứ ai muốn nó.
Thực tế thú vị là nếu tôi sử dụng trường học cũ private
hàm tạo với public static Foo getInstance
accessor, điều này chỉ hoạt động tốt - không có ngoại lệ nào được ném trong khi thiết lập ngữ cảnh.
FWIW, tôi đang sử dụng phiên bản Spring 3.0.5 (cũng đã thử với 3.1.2, cùng một kết quả) với hàm xây dựng o.s.c.s.ClassPathXmlApplicationContext(String ...configLocations)
.
Tôi có thể dễ dàng chuyển đổi mã của mình để sử dụng trình khởi tạo tĩnh nhưng tôi muốn hiểu lý do tại sao Spring hoạt động theo cách này. Đây có phải là một lỗi?
EDIT: Một số điều tra bổ sung cho thấy
- Sau bối cảnh ứng dụng được khởi tạo, tất cả các yêu cầu tiếp theo để
context.getBean(Foo.class)
luôn trở lại cùng một ví dụ củaFoo
. - Thay thế
@Autowired
với bộ định vị (khoảng 20 tập quán đậu này) vẫn cho kết quả nhiều cấu trúc của đối tượng này, nhưng tất cả các phụ thuộc được tiêm cùng một tham chiếu.
Với tôi ở trên cho thấy đây là lỗi mùa xuân liên quan đến việc triển khai @Autowired
. Tôi sẽ đăng lên các diễn đàn cộng đồng Spring và đăng lại ở đây nếu tôi quản lý để có được bất kỳ điều gì hữu ích.
Có thể hiển nhiên nhưng chỉ có 1 JVM khi chơi? Phụ thuộc tròn? –
Có, đây chỉ là một JVM. Thông tư phụ thuộc - có, nhưng tôi tin rằng tôi đã giải thích điều này trong bài viết của mình. – mindas
Tôi hiểu nhưng điều gì sẽ xảy ra nếu bạn có ví dụ như một công cụ xây dựng? Làm thế nào để Spring giải quyết vấn đề đó? –