Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Choose which implementation to inject at runtime spring

I have the following classes:

public interface MyInterface{}

public class MyImpl1 implements MyInterface{}

public class MyImpl2 implements MyInterface{}

public class Runner {
        @Autowired private MyInterface myInterface;
}

What I want to do is decide, whilst the app is already running (i.e. not at startup) which Implementation should be injected into Runner.

So ideally something like this:

ApplicationContext appContext = ...
Integer request = ...

Runner runner = null;
if (request == 1) {
        //here the property 'myInterface' of 'Runner' would be injected with MyImpl1
        runner = appContext.getBean(Runner.class) 
}
else if (request == 2) {
        //here the property 'myInterface' of 'Runner' would be injected with MyImpl2
        runner = appContext.getBean(Runner.class)
}
runner.start();

What is the best way to accomplish this?

like image 938
kwh Avatar asked Oct 07 '13 18:10

kwh


People also ask

Which type of dependency injection is better in Spring?

Constructor Injection —enforcing immutability. This is the most straightforward and recommended way of dependency injection. A dependent class has a constructor, where all dependencies are set, they will be provided by Spring container according to XML, Java or annotation based configurations.

How does Spring implement dependency injection?

Dependency Injection is a fundamental aspect of the Spring framework, through which the Spring container “injects” objects into other objects or “dependencies”. Simply put, this allows for loose coupling of components and moves the responsibility of managing components onto the container.

Which injection is used in Spring boot?

In Spring Boot, we can use Spring Framework to define our beans and their dependency injection. The @ComponentScan annotation is used to find beans and the corresponding injected with @Autowired annotation. If you followed the Spring Boot typical layout, no need to specify any arguments for @ComponentScan annotation.


1 Answers

Declare implementations with @Component("implForRq1") and @Component("implForRq2")

Then inject them both and use:

class Runner {

    @Autowired @Qualifier("implForRq1")
    private MyInterface runnerOfRq1;

    @Autowired @Qualifier("implForRq2")
    private MyInterface runnerOfRq2;

    void run(int rq) {
        switch (rq) {
            case 1: runnerOfRq1.run();
            case 2: runnerOfRq2.run();
            ...

        }
    }

}

...

@Autowired
Runner runner;

void run(int rq) {
    runner.run(rq);
}
like image 148
acc15 Avatar answered Nov 15 '22 05:11

acc15