Allow the APP that created the instance directly to get the instance via the DI container. The advantages of using DI are as follows.
--Scope control --Instance lifecycle control --Built-in common functions --Improved ease of UT by becoming loosely coupled
The Component registered in the DI container is called "Bean". Configuration is called "Bean definition".
--Java-based Configuration
Declared to be a configuration class with @Configuration Bean definition with @Bean
AppConfig.java
@Configuration
public class AppConfig {
@Bean
TestRepository testRepo() {
retrun new TestRepositoryImpl();
}
}
--xml based
Bean definition in
.xml
<beans>
<bean id="test" class="com.test.TestImpl" />
</beands>
--Annotation base
A method of scanning a class with annotations for bean definition and registering it in the DI container (component scan). The most intuitive implementation.
Bean definition side
TestImpl.java
@Component
publi classTestImpl implements Test {
}
User side Add @Autowired to the constructor for automatic injection.
TestImpl.java
@Component
publi class TestUseImpl implements TestUse {
@AutoWired
public TestUseImpl(Test test) {
}
}
There are three methods, but constructor injection seems to be good. Omitted. Constactor injection seems to be recommended because the DI instance becomes final. https://irof.hateblo.jp/entry/2017/04/16/222737 --Setter injection --Constructor injection --field injection
Auto-wiring is a mechanism that automatically injects into a DI container without explicitly defining a bean with @Bean. Internally resolves by type or name. However, if multiple DI containers are defined with the same type, an error will occur because the DI container does not matter which one is used. @Qualifier and @Resouce are used in such cases.
Suppose you register a method that returns the same Convert class in the Bean as shown below.
AppConfig
@Configuration
@ComponentScan
public class AppConfig {
@Bean
Convert getA() {
return new ConvertA();
}
@Bean
Convert getB() {
return new ConvertB();
}
When trying to inject as follows, the pg side cannot determine whether to inject getA
or getB
.
MainService
@Service
public class MainService {
@Autowired
private Convert getA;
public String execute() {
return getA.getConvert();
}
It is possible to separate by explicitly specifying which one to inject with the following description.
@Qualifier("getA")
@Autowired
private Convert getA;
// @Resouce searches the container for the target instance by property name, so
//If the name and the target property name match, it can be omitted.
@Resouce(name = "getA")Or@Resouce
@Autowired
private Convert getA;
Bad example
@Service
public class MainService {
private final Convert getA;
@Resouce(name = "getA")
public MainService (Convert a) {
getA = a;
}
public String execute() {
return getA.getConvert();
}
Recommended Posts