I have web application running with a default impl of a backend service. One should be able to implement the interface and drop the jar into the plugins folder (which is not in the apps classpath). Once the server is restarted, the idea is to load the new jar into the classloader, and have it take part in dependency injection. I am using Spring DI using @Autowired. The new plugin service impl will have @Primary annotation. So given two impls of the interface, the primary should be loaded.
I got the jar loaded into the classloader and can invoke the impl manually. But I haven't been able to get to to participate in the Dependency Injection, and have it replace the default impl.
Here's a simplified example:
Even after I have loaded the jar into the classloader, DefaultService is still being injected as service. Any idea how I get the plugin jar to participate into the spring's DI lifecycle? Or should I avoid going this route at all?Code:@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()"); } } //For lack of better place, I loaded the plugin jar from the 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>


Reply With Quote
