Tôi có ứng dụng web chạy với một impl mặc định của một dịch vụ phụ trợ. Người ta có thể thực hiện giao diện và thả jar vào thư mục plugins (không có trong classpath ứng dụng). Khi máy chủ được khởi động lại, ý tưởng là nạp jar mới vào trình nạp lớp, và có nó tham gia vào việc tiêm phụ thuộc. Tôi đang sử dụng Spring DI bằng cách sử dụng @Autowired. Plugin dịch vụ plugin mới sẽ có chú thích @Primary. Vì vậy, cho hai impls của giao diện, chính nên được nạp.Injection Dependency Spring và Plugin Jar
Tôi đã tải jar vào bộ nạp lớp và có thể gọi impl theo cách thủ công. Nhưng tôi đã không thể tham gia vào Dependency Injection, và có nó thay thế cho impl mặc định.
Dưới đây là một ví dụ đơn giản:
@Controller
public class MyController {
@Autowired
Service service;
}
//default.jar
@Service
DefaultService implements Service {
public void print() {
System.out.println("printing DefaultService.print()");
}
}
//plugin.jar not in classpath yet
@Service
@Primary
MyNewService implements Service {
public void print() {
System.out.println("printing MyNewService.print()");
}
}
// Đối với thiếu nơi tốt đẹp hơn, tôi nạp jar Plugin từ ContextListener
public class PluginContextLoaderListener extends org.springframework.web.context.ContextLoaderListener {
@Override
protected void customizeContext(ServletContext servletContext,
ConfigurableWebApplicationContext wac) {
System.out.println("Init Plugin");
PluginManager pluginManager = PluginManagerFactory.createPluginManager("plugins");
pluginManager.init();
//Prints the MyNewService.print() method
Service service = (Service) pluginManager.getService("service");
service.print();
}
}
<listener>
<listener-class>com.plugin.PluginContextLoaderListener</listener-class>
</listener>
Ngay cả sau khi tôi đã tải jar vào classloader, DefaultService vẫn đang được tiêm dưới dạng dịch vụ. Bất kỳ ý tưởng làm thế nào tôi nhận được các plugin cắm để tham gia vào vòng đời DI của mùa xuân?
Đã chỉnh sửa: Để đơn giản, tôi có tệp chiến tranh có một vài lọ cắm trong thư mục plugin bên trong chiến tranh. Dựa trên một giá trị từ một tệp cấu hình mà ứng dụng xem xét, khi ứng dụng được bắt đầu, tôi muốn tải jar plugin cụ thể đó và chạy ứng dụng với nó. Bằng cách đó, tôi có thể phân phối chiến tranh cho bất kỳ ai và họ có thể chọn plugin để chạy dựa trên giá trị cấu hình mà không phải đóng gói lại mọi thứ. Đây là vấn đề tôi đang cố giải quyết.
Cảm ơn. Có vẻ như điều đó sẽ hiệu quả. Nhưng tôi đang sử dụng chú thích mùa xuân rất nhiều, và không có bất kỳ xml mùa xuân nào trong các lọ cắm. Tôi tự hỏi làm thế nào nó sẽ dễ dàng để làm tương tự như trên cho tiêm phụ thuộc chú thích theo định hướng. – Langali
Bạn nên có một số loại cấu hình trong mỗi plugin của bạn (@xem câu trả lời mở rộng của tôi). Thậm chí nếu nó chỉ là một xml nhỏ chỉ với một phần tử ' ' của gói plugin, nó sẽ là ** trong plugin ** và không có nơi nào khác. Đây là plugin tự biết rõ nhất và biết cách cấu hình chính nó. Mô-đun cốt lõi không nên biết về sự tồn tại của plugin - nó chỉ nên cung cấp cho chúng khả năng tham gia các cấu hình của riêng chúng tới 'ApplicationContext'. –
Roadrunner