Thursday, January 25, 2018

Integrating Spring with a legacy app

Spring is a behemoth and doesn't play well with others, preferring to take over all aspects of an application - inversion of control gone wild. The best bet is to avoid it entirely, but if you're stuck with Spring for whatever reason, and want to implement something non-trivial, you're likely to need to integrate it with non-spring POJO objects - what the Spring fan-persons call "Legacy Applications"

To inject a non-spring POJO into a Spring Boot application:

  • create an ApplicationListener
  • in the listener call registerSingleton with the non-spring object
  • register the listener with the app

this allows the field to be initialized early during the application lifecycle
@RestController @SpringBootApplication public class SpringLegacy { public SpringLegacy() {} @Lazy @Autowired @Qualifier("legacyBean") Object myBean; @RequestMapping("/dir") public Object dir() { return "hello world " + myBean; } static class LegacyObject {} public static void main(final String[] args) throws Exception { Object obj = new LegacyObject(); SpringApplication app = new SpringApplication(SpringLegacy.class); ApplicationListener lis = new ApplicationListener() { boolean first = true; @Override public void onApplicationEvent(ApplicationEvent event) { if (first & event instanceof ContextRefreshedEvent) { ((GenericApplicationContext) (((ContextRefreshedEvent) event).getApplicationContext())). getBeanFactory().registerSingleton("legacyBean", obj); first = false; } } }; app.setListeners(Arrays.asList(lis)); app.run(args); } }
full source is https://github.com/nqzero/spring-legacy
run the maven project, and then browse to localhost:8080/dir - you should see "LegacyObject" in the output

No comments: