I implemented spring-boot application and now I want to use it as a lib for non-spring application. How can I initialize lib classes so autowired dependencies work as expected?Obviously if I create class instance with 'new', all autowired dependencies will be null.
-
2There's no easy or obvious way to do this. I'm not even sure if doing it makes any sense.Robert Moskal– Robert Moskal2015-06-17 20:25:49 +00:00Commented Jun 17, 2015 at 20:25
-
1If you designed your application properly (i.e. not using field injection or anything else that needs Spring magic to run) you should be able to instantiate and wire all your components programmatically, by hand. However, it looks like a better solution would be to extract the part you'd be sharing into a proper library that does not depend on Spring at all.kryger– kryger2015-06-17 21:36:19 +00:00Commented Jun 17, 2015 at 21:36
-
My application is designed 'properly': I haven't use field injection. Primarily it uses constructor injection and in some cases(optional parameters) setter injection. But it will not help a lot, since components dependencies are going by chain. For example, I have entry point class with constructor argument Class1. Class1 has constructor argument Class2. Class2 has constructor argument Class3 etc. On instantiation I will have something like: new EntryPointClass(new Class1(new Class2(new Class3(....)))) So, instantiate by hand is like to write in Java all Spring configuration I have :)Aram Aslanyan– Aram Aslanyan2015-06-17 22:39:55 +00:00Commented Jun 17, 2015 at 22:39
-
1@AramAslanyan Looking to do the same, If you are able to do it could you please share it will be of great help to the communityuser2359997– user23599972019-09-01 15:55:39 +00:00Commented Sep 1, 2019 at 15:55
-
I don't know how you use an application as a library. That makes no sense to me. You will need to explain in more detail what you want to do with at least some semblance of an SSCCE. If you want to run an application server inside another application, for example, then you need to consider port conflicts and shared resources.Boris the Spider– Boris the Spider2019-09-01 16:04:48 +00:00Commented Sep 1, 2019 at 16:04
2 Answers
The theory is that you need to instantiate an application context for your Spring Boot dependency to live in, then extract a bean from there and make use of it.
In practice, in your Spring Boot dependency you should have an Application.java class or similar, in which a main method starts the application. Start by adding there a method like this:
public static ApplicationContext initializeContext(final String[] args) {
return SpringApplication.run(Application.class, args);
}
Next step, in you main application, when you see fit (I'd say during startup but might as well be the first time you need to use your dependency) you need to run this code:
final String[] args = new String[0]; // configure the Spring Boot app as needed
final ApplicationContext context = Application.initializeContext(args); // createSpring application context
final YourBean yourBean = (YourBean)context.getBean("yourBean"); // get a reference of your bean from the application context
From here you can use your beans as you see fit.
Comments
I'm not sure how you will handle to wait until the context is fully loaded before you try to access some beans from your Constructor etc. But if you just want to access context without creating components manually try one of those:
1) Simply Inject ApplicationContext
@Inject
private ApplicationContext context;
or
2) Implement ApplicationContextAware
public class ApplicationContext implements ApplicationContextAware {
private ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext context) {
this.context = context;
}
// just quick example, better to set it to your custom singleton class
public static ApplicationContext getContext() {
return context;
}
}
Then use context.getBean(SomeServiceFromLibrary.class);