Sử dụng Cấu hình Java của Spring, tôi cần thu thập / khởi tạo một bean có phạm vi nguyên mẫu với các đối số hàm tạo chỉ có thể nhận được khi chạy. Xem xét ví dụ mã sau (đơn giản hóa cho ngắn gọn):
@Autowired
private ApplicationContext appCtx;
public void onRequest(Request request) {
//request is already validated
String name = request.getParameter("name");
Thing thing = appCtx.getBean(Thing.class, name);
//System.out.println(thing.getName()); //prints name
}
trong đó lớp Thing được định nghĩa như sau:
public class Thing {
private final String name;
@Autowired
private SomeComponent someComponent;
@Autowired
private AnotherComponent anotherComponent;
public Thing(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
Lưu ý name
là final
: nó chỉ có thể được cung cấp thông qua một nhà xây dựng và đảm bảo tính bất biến. Các phụ thuộc khác là các phụ thuộc dành riêng cho việc thực hiện của Thing
lớp và không nên biết (kết hợp chặt chẽ với) việc thực hiện xử lý yêu cầu.
Mã này hoạt động hoàn toàn tốt với cấu hình Spring XML, ví dụ:
<bean id="thing", class="com.whatever.Thing" scope="prototype">
<!-- other post-instantiation properties omitted -->
</bean>
Làm cách nào để đạt được điều tương tự với cấu hình Java? Cách sau không hoạt động khi sử dụng Spring 3.x:
@Bean
@Scope("prototype")
public Thing thing(String name) {
return new Thing(name);
}
Bây giờ, tôi có thể tạo một Nhà máy, ví dụ:
public interface ThingFactory {
public Thing createThing(String name);
}
Nhưng điều đó đánh bại toàn bộ quan điểm sử dụng Spring để thay thế mẫu thiết kế ServiceLocator và Factory , sẽ rất lý tưởng cho trường hợp sử dụng này.
Nếu Spring Java Config có thể làm điều này, tôi có thể tránh:
- xác định giao diện Factory
- xác định thực hiện Nhà máy
- kiểm tra viết cho việc thực hiện Nhà máy
Đó là một tấn công việc (tương đối nói) cho một cái gì đó tầm thường mà Spring đã hỗ trợ thông qua cấu hình XML.
Thing
thực hiện thực sự phức tạp hơn và không có sự phụ thuộc vào các loại đậu khác (tôi chỉ bỏ qua chúng cho ngắn gọn). Như vậy, tôi không muốn triển khai Trình xử lý yêu cầu biết về chúng, vì điều này sẽ kết hợp chặt chẽ trình xử lý với API / đậu mà nó không cần. Tôi sẽ cập nhật câu hỏi để phản ánh câu hỏi (xuất sắc) của bạn.
@Qualifier
các tham số cho một setter với @Autowired
chính setter đó.
@Bean
các tác phẩm. Các @Bean
phương pháp được gọi với các đối số thích hợp bạn truyền cho getBean(..)
.