2

I am working on a module which needs spring beans to be created at runtime. My driver app is a spring boot app, it needs to create a bean (which is outside the component scan packages of the app) and invoke a method in that bean. Fully qualified class name and method name will be runtime parameters. Below is an example:

Bean to be created:

@Component
@ComponentScan(basePackages = {"com.test"})
public class TestClass {

    @Autowired
    private AnotherTestClass anotherTest;

    public void test(){
        System.out.println("In test");
        anotherTest.test();
    }

}

Here is the driver class code (which obviously doesn't work):

public void test(){
    try{
        Class testClass = Class.forName("com.test.TestClass");
        Object newInstance = testClass.newInstance();
        applicationContext.getAutowireCapableBeanFactory().autowireBean(newInstance);
        Method testMetod = testClass.getMethod("test");
        testMetod.invoke(newInstance, null);
    }catch(Exception e){
        e.printStackTrace();
    }
}

Here, applicationContext is autowired. As it is instantiating the class via reflection, the object won't have autowired dependency set. What I want to achieve is, to scan all the packages (as mentioned in the component scan annotation), create the beans and set the dependencies. i.e. I want to do exactly the same as what spring does when application starts, but at runtime. Also, I want it to be completely generic as the beans will mostly be residing in external jars and fully qualified class path and method name will be passed at runtime (like a pluggable architecture).

Any ideas how to achieve this?

Darshan Mehta
  • 30,102
  • 11
  • 68
  • 102
  • Thought of delegating this to a prototype bean that then does what your test() does ? Besides that you might want to read this: http://meta.stackoverflow.com/questions/288160/no-thanks-damn-it ;-) – Marged Dec 16 '15 at 12:10
  • Why? Seems like a horrid complex situation. Assuming everything has the same base package (`com.company`) just scan the package and construct the components. If you want a pluggable architecture use something like OSGi or the Java Services API. If all else fails you could even use `@Configurable` to have dependencies injected in classes constructed outside of Spring. – M. Deinum Dec 16 '15 at 12:12
  • the question is Why? – reos Dec 16 '15 at 13:37
  • We already have a spring application running and I am just exploring the options for how to add a pluggable service layers into the existing app. – Darshan Mehta Dec 16 '15 at 13:42
  • Better to use OSGi for that. I think with Spring your best option is to reinitialize the entire application context. – erosb Dec 16 '15 at 14:26

0 Answers0