Dependency Injection
Dependency Injection, DI ๋ ์์กด๊ด๊ณ ์ฃผ์ ์ผ๋ก Spring ํ๋ ์์ํฌ์์ ์ ๊ณตํ๋ IoC ์ ํํ์ด๋ค. ํด๋์ค ์ฌ์ด์ ์์กด๊ด๊ณ๋ฅผ ๋น ์ค์ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก ์ปจํ ์ด๋๊ฐ ์๋์ผ๋ก ์ฐ๊ฒฐํด์ค๋ค.
DI ๋ฅผ ํตํด ์์กด์ฑ์ ์ฃผ์ ํ๋ฉด ๋ชจ๋ ๊ฐ์ ๊ฒฐํฉ๋๊ฐ ๋ฎ์์ง๊ณ ์ ์ฐ์ฑ์ด ๋์์ง๋ ์ฅ์ ์ ํ์ฉํ ์ ์๋ค.
์คํ๋ง์์ ์คํ๋ง ์ปจํ
์ด๋ ApplicationContext
๋ฅผ ํตํด ์ค์ ์ ๋ณด๋ฅผ ์์ฑ ๋ฐ ๋ฑ๋กํ๊ณ ๊ฐ์ฒด๋ฅผ ์์ฑ์ ํน์ setter
๋ฅผ ํตํด ์ฃผ์
ํ๋ค.
DI ์ข ๋ฅ
์์ฑ์ ์ฃผ์
@Service
public class Service {
private final Repository repository;
public Service(Repository repository) {
this.repository = repository;
}
}
์์ฑ์๋ฅผ ํตํด ์์กด์ฑ์ ์ฃผ์ ํ๋ ๋ฐฉ์์ด๋ค. ์์กด ๊ด๊ณ๋ฅผ ๋ชจ๋ ์ฃผ์ ํด์ผ ๊ฐ์ฒด ์์ฑ์ด ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ NPE ๋ฅผ ๋ฐฉ์งํ ์ ์๋ค. ์์กด ๊ด๊ณ๊ฐ ๋ง์์ง ๊ฒฝ์ฐ ์์ฑ์๊ฐ ๊ธธ์ด์ ธ SRP ์์น์ ์๊ธฐ์์ผ์ฃผ๊ธฐ๋ ํ๋ค.
์ถ๊ฐ์ ์ธ ์ค์ ์ด ํ์ํ์ง ์๊ณ ๋ปํ์ง ์๊ฒ ์์กด์ฑ๊ณผ ์ค์ ๊ฐ์ ๋น ๋จ๋ฆฌ๋ ์ผ์ด ์์ผ๋ฉฐ, ํ ์คํธํ๊ธฐ์๋ ์ฉ์ดํ๊ธฐ์ ๊ฐ์ฅ ๊ถ์ฅ๋๋ ์ฃผ์ ๋ฐฉ์์ด๋ค.
ํน์ง
- ์์ฑ์ ํธ์ถ์์ ์ ๋ฑ 1๋ฒ๋ง ํธ์ถ๋๋ ๊ฒ์ด ๋ณด์ฅ๋จ
- ๋ถ๋ณ, ํ์ ์์กด๊ด๊ณ์ ์ฌ์ฉ
- ์์ฑ์๊ฐ 1๊ฐ๋ง ์์ผ๋ฉด
@Autowired
์๋ต ๊ฐ๋ฅ
Setter ์ฃผ์
@Service
public class Service {
private Repository repository;
public void setRepository(Repository repository) {
this.repository = repository;
}
}
setter
๋ฅผ ํตํด ์์กด์ฑ์ ์ฃผ์
ํ๋ค. ์ ํ์ ์ผ๋ก ์์กด์ฑ์ ์ฃผ์
ํ ์ ์๊ธฐ ๋๋ฌธ์ ๋ชจ๋ ์์กด์ฑ์ ์ฃผ์
๋ฐ์ง ์๊ณ ๋ ๊ฐ์ฒด ์์ฑ์ด ๊ฐ๋ฅํ๋ค. ๋๋ฌธ์ NPE ๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ๋๋ค.
ํน์ง
- ์ ํ, ๋ณ๊ฒฝ ๊ฐ๋ฅ์ฑ์ด ์๋ ์์กด๊ด๊ณ์์ ์ฌ์ฉ
- Java Bean Property ๊ท์ฝ์ ์์ ์ ๋ฉ์๋ ๋ฐฉ์์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
@Autowired
์ ๊ธฐ๋ณธ ๋์์ ์ฃผ์ ํ ๋์์ด ์์ผ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค. ์ฃผ์ ํ ๋์์ด ์์ด๋ ๋์ํ๊ฒ ํ๋ ค๋ฉด@Autowired(required = false)
๋ก ์ง์ ํ๋ฉด ๋๋ค.
ํ๋ ์ฃผ์
@Service
public class Service {
@Autowired
private Repository repository;
}
@Autowired
์ ๋ํ
์ด์
์ ํตํด ์์กด์ฑ ์ฃผ์
ํ๋ค. ์์กด์ฑ ์ฃผ์
์ด ์ฝ๊ธฐ ๋๋ฌธ์ SRP ์์น์ ์๋ฐฐํ ๊ฐ๋ฅ์ฑ์ด ๋๋ค. ์ฌ์ฉํ๊ธฐ ํธ๋ฆฌํ ๋งํผ ๋จ์ ๋ ๋ง์ ๋ฐฉ์์ด๋ค.
DI ํ๋ ์์ํฌ ์์ด๋ ์๋ํ๊ธฐ ํ๋ค๋ฉฐ, ์ธ๋ถ์์ ๋ณ๊ฒฝ์ด ๋ถ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ํ ์คํธํ๊ธฐ ํ๋ค๋ค.
์ฃผ๋ก ์ ํ๋ฆฌ์ผ์ด์
๊ณผ ๊ด๊ณ์๋ ํ
์คํธ์ฝ๋๋ @Configuration
๊ณผ ๊ฐ์ ์คํ๋ง ์ค์ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉํ๋ค.
ํน์ง
- ์ธ๋ถ์์ ๋ณ๊ฒฝ์ด ๋ถ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ์คํ๋ง ์ปจํ ์ด๋๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ์์ํ ์๋ฐ ์ฝ๋๋ก ํ ์คํธํ๊ธฐ ์ด๋ ค์
- ์ ํ๋ฆฌ์ผ์ด์ ์ ์ค์ ์ฝ๋์ ๊ด๊ณ ์๋ ํ ์คํธ ์ฝ๋์ ์ฌ์ฉ
- ์คํ๋ง ์ค์ ์ ๋ชฉ์ ์ผ๋ก ํ๋
@Configuration
๊ฐ์ ๊ณณ์์ ํน๋ณํ ์ฉ๋๋ก ์ฌ์ฉ
์ผ๋ฐ ๋ฉ์๋ ์ฃผ์
- ์ผ๋ฐ ๋ฉ์๋๋ฅผ ํตํด ์ฃผ์ ํ๋ ๋ฐฉ๋ฒ
- ํน์ง
- ํ ๋ฒ์ ์ฌ๋ฌ ํ๋๋ฅผ ์ฃผ์ ๋ฐ์ ์ ์์
- ์ผ๋ฐ์ ์ผ๋ก ์ ์ฌ์ฉํ์ง ์์
์ต์ ์ฒ๋ฆฌ
์ฃผ์
ํ ์คํ๋ง ๋น์ด ์์ด๋ ๋์ํด์ผ ํ ๋๊ฐ ์๋ค. ๊ทธ๋ฐ๋ฐ @Autowired
๋ง ์ฌ์ฉํ๋ฉด required = true
๊ฐ ๊ธฐ๋ณธ๊ฐ์ด๊ธฐ ๋๋ฌธ์ ์๋ ์ฃผ์
๋์์ด ์์ผ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
์๋ ์ฃผ์
๋์์ ์ต์
์ผ๋ก ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ๋ค.
@Autowired(required=false)
- ์๋ ์ฃผ์ ๋์์ด ์์ผ๋ฉด ์์ ์ ๋ฉ์๋ ์์ฒด๊ฐ ํธ์ถ ์๋จ
@Nullable
- ์๋ ์ฃผ์
๋์์ด ์์ผ๋ฉด
null
์ด ์ ๋ ฅ๋จ
- ์๋ ์ฃผ์
๋์์ด ์์ผ๋ฉด
Optional<>
- ์๋ ์ฃผ์
๋์์ด ์์ผ๋ฉด
Optional.empty
๊ฐ ์ ๋ ฅ๋จ
- ์๋ ์ฃผ์
๋์์ด ์์ผ๋ฉด
์์ฑ์ ์ฃผ์ ์ ์ ํํด๋ผ!
๊ณผ๊ฑฐ์๋ ์์ ์ ์ฃผ์ ๊ณผ ํ๋ ์ฃผ์ ์ ๋ง์ด ์ฌ์ฉํ์ง๋ง, ์ต๊ทผ์๋ ์คํ๋ง์ ํฌํจํ DI ํ๋ ์์ํฌ ๋๋ถ๋ถ์ด ์์ฑ์ ์ฃผ์ ์ ๊ถ์ฅํ๋ค. ๊ทธ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ๋ค.
๋ถ๋ณ
- ๋๋ถ๋ถ์ ์์กด๊ด๊ณ ์ฃผ์ ์ ํ ๋ฒ ์ผ์ด๋๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ข ๋ฃ๋ ๋ ๊น์ง ์์กด๊ด๊ณ๋ฅผ ๋ณ๊ฒฝํ ์ผ์ด ์๋ค. ์คํ๋ ค ๋๋ถ๋ถ์ ์์กด๊ด๊ณ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ข ๋ฃ ์ ๊น์ง ๋ณํ๋ฉด ์๋๋ค.
- ์์ ์ ์ฃผ์ ์ ์ฌ์ฉํ๋ฉด setter ๋ฅผ public ์ผ๋ก ์ด์ด๋์ด์ผ ํ๋ค.
- ๋๊ตฐ๊ฐ ์ค์๋ก ๋ณ๊ฒฝํ ์ ๋ ์๊ณ , ๋ณ๊ฒฝํ๋ฉด ์๋๋ ๋ฉ์๋๋ฅผ ์ด์ด๋๋ ๊ฒ์ ์ข์ ์ค๊ณ๊ฐ ์๋๋ค.
- ์์ฑ์ ์ฃผ์ ์ ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ ๋ฑ 1๋ฒ๋ง ํธ์ถ๋๋ฏ๋ก ์ดํ์ ํธ์ถ๋๋ ์ผ์ด ์๋ค. ๋ฐ๋ผ์ ๋ถ๋ณํ๊ฒ ์ค๊ณํ ์ ์๋ค.
๋๋ฝ
- ์์ ์ ์ฃผ์
์ ์ฌ์ฉํ๋ฉด ์คํ๋ง์
@Autowired
์์ด ์์ํ ์๋ฐ ์ฝ๋์์ ์์กด๊ด๊ณ๋ฅผ ๋๋ฝํ ๊ฐ๋ฅ์ฑ์ด ์๊ธด๋ค. - ์์ฑ์ ์ฃผ์ ์ ์ฌ์ฉํ๋ฉด ์ปดํ์ผ ์ค๋ฅ๋ก ๋ฏธ๋ฆฌ ์ก์๋ผ ์ ์๋ค.
final ํค์๋
- ์์ฑ์ ์ฃผ์
์ ์ฌ์ฉํ๋ฉด
final
ํค์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค. ์ด๋ฅผ ํตํด ๊ฐ์ด ์ค์ ๋์ง ์๋ ์ค๋ฅ๋ฅผ ์ปดํ์ผ ์์ ์ ์์๋ผ ์ ์๋ค. - ๋ค๋ฅธ ์ฃผ์
๋ฐฉ์์ ๋ชจ๋ ์์ฑ์ ์ดํ์ ํธ์ถ๋๊ธฐ ๋๋ฌธ์
final
ํค์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
์ ๋ฆฌ
- ์์ฑ์ ์ฃผ์ ๋ฐฉ์์ ์ ํํ๋ ์ด์ ๋ ์ฌ๋ฌ๊ฐ์ง๊ฐ ์์ง๋ง, ํ๋ ์์ํฌ์ ์์กดํ์ง ์๊ณ , ์์ํ ์๋ฐ ์ธ์ด์ ํน์ง์ ์ ์ด๋ฆฌ๋ ๋ฐฉ๋ฒ์ด๊ธฐ๋ ํ๋ค.
- ๊ธฐ๋ณธ์ผ๋ก ์์ฑ์ ์ฃผ์ ์ ์ฌ์ฉํ๊ณ , ํ์ ๊ฐ์ด ์๋ ๊ฒฝ์ฐ์๋ ์์ ์ ์ฃผ์ ๋ฐฉ์์ ์ต์ ์ผ๋ก ๋ถ์ฌํ๋ฉด ๋๋ค. ์์ฑ์ ์ฃผ์ ๊ณผ ์์ ์ ์ฃผ์ ์ ๋์์ ์ฌ์ฉํ ์ ์๋ค.
๋กฌ๋ณต๊ณผ ์ต์ ํธ๋ ๋
๋ง์ ๊ฐ๋ฐ์ ํด๋ณด๋ฉด, ๋๋ถ๋ถ์ด ๋ค ๋ถ๋ณ์ด๊ณ , ๊ทธ๋์ ๋ค์๊ณผ ๊ฐ์ด ์์ฑ์์ final
ํค์๋๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ค. ๊ทธ๋ฐ๋ฐ ์์ฑ์๋ ๋ง๋ค์ด์ผ ํ๊ณ , ์ฃผ์
๋ฐ์ ๊ฐ์ ๋์
ํ๋ ์ฝ๋๋ ๋ง๋ค์ด์ผ ํ๊ณ โฆ
ํ๋ ์ฃผ์
์ฒ๋ผ ์ข ํธ๋ฆฌํ๊ฒ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์์๊น?
- ๋กฌ๋ณต ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ ๊ณตํ๋
@RequiredArgsConstructor
๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ฉดfinal
์ด ๋ถ์ ํ๋๋ฅผ ๋ชจ์์ ์์ฑ์๋ฅผ ์๋์ผ๋ก ๋ง๋ค์ด์ค๋ค. - ๋กฌ๋ณต์ด ์๋ฐ์ ์ ๋ ธํ ์ด์ ํ๋ก์ธ์๋ผ๋ ๊ธฐ๋ฅ์ ์ด์ฉํด์ ์ปดํ์ผ ์์ ์ ์์ฑ์ ์ฝ๋๋ฅผ ์๋์ผ๋ก ์์ฑํด์ค๋ค. ์ค์ class ๋ฅผ ์ด์ด๋ณด๋ฉด ๋ค์ ์ฝ๋๊ฐ ์ถ๊ฐ๋์ด ์๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
- ์ต๊ทผ์๋ DI ๋ฅผ ํ ๋ ์์ฑ์๋ฅผ ๋ฑ 1๊ฐ ๋๊ณ ,
@Autowired
๋ฅผ ์๋ตํ๋ ๋ฐฉ๋ฒ์ ์ฃผ๋ก ์ฌ์ฉํ๋ค. ์ฌ๊ธฐ์ Lombok ๋ผ์ด๋ธ๋ฌ๋ฆฌ์@RequiredArgsConstructor
ํจ๊ป ์ฌ์ฉํ๋ฉด ๊ธฐ๋ฅ์ ๋ค ์ ๊ณตํ๋ฉด์, ์ฝ๋๋ ๊น๋ํ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
๋กฌ๋ณต ์ ์ฉ
plugins {
id 'org.springframework.boot' version '2.7.1'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'hello'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
// lombok
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
// lombok
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
// lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testCompileOnly 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
// lombok
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
- Preferences โ plugin โ lombok ์ค์น ํ ์ฌ์์
- Preferences โ Annotation Processors ๊ฒ์ โ Enable annotation processing ์ฒดํฌ
์กฐํ ๋น์ด 2๊ฐ ์ด์ - ๋ฌธ์
@Autowired
๋ ํ์
์ผ๋ก ๋น์ ํ์
2๊ฐ์ผ ๊ฒฝ์ฐ ๋ฌธ์ ๋ฐ์
@Autowired ํ๋ ๋ช , @Qualifer, @Primary
์กฐํ ๋์ ๋น์ด 2๊ฐ ์ด์์ผ ๋
@Autowired
ํ๋๋ช ๋งค์นญ@Qualifier
โ@Qualifier
๋ผ๋ฆฌ ๋งค์นญ โ ๋น ์ด๋ฆ ๋งค์นญ@Primary
์ฌ์ฉ
์ด๋ ธํ ์ด์ ์ง์ ๋ง๋ค๊ธฐ
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Qualifier("mainDiscountPolicy")
public @interface MainDiscountPolicy {
}
- ์ ๋ ธํ ์ด์ ์๋ ์์์ด๋ผ๋ ๊ฐ๋ ์ด ์์
- ์ฌ๋ฌ ์ ๋ ธํ ์ด์ ์ ๋ชจ์์ ์ฌ์ฉํ๋ ๊ธฐ๋ฅ์ ์คํ๋ง์ด ์ง์ํด์ฃผ๋ ๊ธฐ๋ฅ