Dependency Injection with Spring 5
public class IntelCorei9_9900K {
private int cores;
private int cache;
}
public class IntelPentiumGold_G550 {
private int cores;
private int cache;
}
As we can see, for now they are both identical. Both of them will have a method getInfo(), so now we will create an interface called ICPU containing the method getInfo() and both of our classes will implement this interface (code to an interface).
public interface ICPU {
String getInfo();
}
The next step is to implement this interface in our CPU classes.
public class IntelCorei9_9900K implements ICPU {
private int cores;
private int cache;
@Override
public String getInfo() {
return "Model: Intel Core i9-9900K" + ", cores: " + this.cores + ", cache: " + this.cache + "MB";
}
}
public class IntelPentiumGold_G550 implements ICPU {
private int cores;
private int cache;
@Override
public String getInfo() {
return "Model: Intel Pentium Gold G550" + ", cores: " + this.cores + ", cache: " + this.cache + "MB";
}
}
We now have to set different values for our fields. We do that using the @Value annotation for each of our fields.
public class IntelCorei9_9900K implements ICPU {
@Value("8")
private int cores;
@Value("16")
private int cache;
@Override
public String getInfo() {
return "Model: Intel Core i9-9900K" + ", cores: " + this.cores + ", cache: " + this.cache + "MB";
}
}
public class IntelPentiumGold_G550 implements ICPU {
@Value("2")
private int cores;
@Value("2")
private int cache;
@Override
public String getInfo() {
return "Model: Intel Pentium Gold G550" + ", cores: " + this.cores + ", cache: " + this.cache + "MB";
}
}
The next step is to annotate each of our classes with the @Component annotation telling Spring that this class should be used as a Bean.
@Component
public class IntelCorei9_9900K implements ICPU {
@Component
public class IntelPentiumGold_G550 implements ICPU {
Now we create our Computer class which looks as follows:
@Component
public class Computer {
private ICPU cpu;
@Autowired //optional
public Computer(ICPU cpu) {
this.cpu = cpu;
}
public String getPCInfo() {
return cpu.getInfo();
}
}
@Autowired
public void setCPU(ICPU cpu) {
this.cpu = cpu;
}
The field – based dependency injection is considered as bad practice so it won’t be viewed in this tutorial.
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(DemoApplication.class, args);
Computer computer = (Computer) context.getBean("computer");
System.out.println(computer.getPCInfo());
}
Parameter 0 of constructor in com.example.demo.model.Computer required a single bean, but 2 were found:
- intelCorei9_9900K: defined in file [E:\intelliJ\Examples for Knowledge Base\PC-DI\demo\target\classes\com\example\demo\model\IntelCorei9_9900K.class]
- intelPentiumGold_G550: defined in file [E:\intelliJ\Examples for Knowledge Base\PC-DI\demo\target\classes\com\example\demo\model\IntelPentiumGold_G550.class]
It is caused because the autowiring in the Computer constructor is ambiguous. The framework doesn’t know which of the CPU classes implementing our ICPU interface to use. One way to specify the exact class that we want to use is to add the @Qualifier annotation to our classes and to the Computer constructor (or setter).
@Component
@Qualifier("i9")
public class IntelCorei9_9900K implements ICPU {
@Component
@Qualifier("pentium")
public class IntelPentiumGold_G550 implements ICPU {
Then in the Computer constructor we specify which one of the implementations we want to inject. In the example we choose that we want the Pentium implementation.
@Autowired //optional
public Computer(@Qualifier("pentium") ICPU cpu) {
this.cpu = cpu;
}
In case we used the setter-based dependency injection we complete it adding the @Qualifier annotation as shown.
@Autowired
@Qualifier("pentium")
public void setCPU(ICPU cpu) {
this.cpu = cpu;
}
If we run the main method again we get the following result.
2020-07-11 22:23:09.082 INFO 10516 --- [ restartedMain] com.example.demo.DemoApplication : Starting DemoApplication on DESKTOP-9VUF3IS with PID 10516 (started by Dany in E:\intelliJ\Examples for Knowledge Base\PC-DI\demo)
2020-07-11 22:23:09.082 INFO 10516 --- [ restartedMain] com.example.demo.DemoApplication : No active profile set, falling back to default profiles: default
2020-07-11 22:23:09.172 INFO 10516 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2020-07-11 22:23:10.592 INFO 10516 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2020-07-11 22:23:10.672 INFO 10516 --- [ restartedMain] com.example.demo.DemoApplication : Started DemoApplication in 2.12 seconds (JVM running for 3.174)
Model: Intel Pentium Gold G550, cores: 2, cache: 2MB
Process finished with exit code 0
And that’s it. We successfully used the Spring 5 Framework to manage our dependency injection.
Letzte Beiträge
Share :
Share :
Weitere Beiträge
Dependency Injection
Each Object-oriented application consists of many classes that work together in order to solve a problem. However, when writing a complex application, application classes should be as independent as possible.
View Model. Example
In this article we will go through the steps of creating a simple game screen. We will make it the traditional way without using View Model and we will see why it is absolutely wrong to persist data in the View.
ViewModel
ViewModel – it is a model of the view. The purpose of the ViewModel is to apply any business logic to the Model before exposing it to the View for consumption. This way the View is free of business logic.