[JAVA] Spring Basics ~ DI Edition ~

About DI

What is DI

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".

Implementation method using DI

Configuration method

--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 element. Bean name in id attribute, Class attribute defined as an instance of Bean of that class

.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) {
    }
}

Type of injection

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

About auto wiring

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.

Qualifier and Resource

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

Spring Basics ~ DI Edition ~
[Java] Spring DI ③
About DI of Spring ①
First Spring Boot (DI)
About DI of Spring ②
[For beginners] DI ~ The basics of DI and DI in Spring ~
Introduction to Spring Boot ① ~ DI ~
[Java] How Spring DI works
About Spring DI related annotations
[Java] Spring DI ④ --Life cycle management
Spring Framework study notes [Part 1] DI container
DI SessionScope Bean in Spring Boot 2 Filter