Bibi's DevLog ๐ค๐
[Spring] ์ธํ๋ฐ ์คํ๋ง ์ ๋ฌธ(๊น์ํ ๋) - ์คํ๋ง ๋น๊ณผ ์์กด๊ด๊ณ : ์ปดํฌ๋ํธ ์ค์บ, ์์กด๊ด๊ณ, DI, ์คํ๋ง ๋น ์ง์ ๋ฑ๋กํ๊ธฐ ๋ณธ๋ฌธ
[Spring] ์ธํ๋ฐ ์คํ๋ง ์ ๋ฌธ(๊น์ํ ๋) - ์คํ๋ง ๋น๊ณผ ์์กด๊ด๊ณ : ์ปดํฌ๋ํธ ์ค์บ, ์์กด๊ด๊ณ, DI, ์คํ๋ง ๋น ์ง์ ๋ฑ๋กํ๊ธฐ
๋น๋น bibi 2021. 3. 4. 23:59์ด ๊ธ์ ์ธํ๋ฐ ๊น์ํ ๋์ ์คํ๋ง ์ ๋ฌธ ๊ฐ์ ๋ฅผ ๋ฃ๊ณ ์ ๋ฆฌํ ๊ธ์ ๋๋ค.
์คํ๋ง ๋น๊ณผ ์์กด๊ด๊ณ
์ปดํฌ๋ํธ ์ค์บ๊ณผ ์๋ ์์กด๊ด๊ณ ์ค์ , DI
๋ง๋ ์๋น์ค๋ฅผ ํ๋ฉด์ ๋ถ์ด๊ธฐ ์ํด ์ปจํธ๋กค๋ฌ์ Viewํ ํ๋ฆฟ์ด ํ์ํ๋ค.
์๋ฅผ ๋ค์ด ํ์๊ฐ์ ์ ํ๋ฉด ๊ทธ ๊ฒฐ๊ณผ๋ฅผ HTML๋ก ํ๋ฉด์ ๋ฟ๋ ค์ฃผ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ธ ๊ฒ.
๋จผ์ Member์ Controller๋ฅผ ๋ง๋ค์ด์ผ ํ๋ค.
์์กด๊ด๊ณ
Controller๋ Service๋ฅผ ํตํด ํ์๊ฐ์ ์ ํ๊ณ , ๋ฐ์ดํฐ๋ฅผ ์กฐํํ ์ ์์ด์ผ.
์ด๋ฅผ '์ปจํธ๋กค๋ฌ๊ฐ ์๋น์ค์ ์์กดํ๊ณ ์๋ค'๊ณ ํํํ๋ฉฐ, '์์กด๊ด๊ณ๊ฐ ์๋ค'๊ณ ํ ์ ์๋ค.
ํ์ ์ปจํธ๋กค๋ฌ๊ฐ ํ์ ์๋น์ค์ ๋ฆฌํฌ์งํ ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ์์กด๊ด๊ณ๋ฅผ ๋ง๋ค์.
์คํ๋ง ์ปจํ ์ด๋์ ์คํ๋ง ๋น
@Controller
์ด๋
ธํ
์ด์
์ผ๋ก ์ปจํธ๋กค๋ฌ๋ฅผ ๋ง๋ค์ด ๋๋ฉด,
์คํ๋ง ๋ถํธ๊ฐ ์คํ๋ ๋ ์คํ๋ง ์ปจํ ์ด๋๊ฐ ํด๋น '์ปจํธ๋กค๋ฌ ๊ฐ์ฒด'๋ฅผ ์์ฑํด ์คํ๋ง ์ปจํ ์ด๋์ ๋ฃ์ด ๋๋ฉฐ ํด๋น ๊ฐ์ฒด๋ ์คํ๋ง์ด ๊ด๋ฆฌํ๋ ๋์์ด ๋๋ค.
์ด๋ฅผ '์คํ๋ง ์ปจํ ์ด๋์์ ์คํ๋ง ๋น์ด ๊ด๋ฆฌ๋๋ค' ๊ณ ํ๋ค.
์คํ๋ง์ ์ํด ๊ด๋ฆฌ๋๋๋ก ํ๋ ค๋ฉด, ๊ทธ ๋์์ ์คํ๋ง ์ปจํ ์ด๋์ ๋ฑ๋กํด์ผ ํ๋ฉฐ, ์ฌ์ฉํ ๋๋ ์คํ๋ง ์ปจํ ์ด๋๋ก๋ถํฐ ๋ฐ์์ ์ฐ๋๋ก ์ค๊ณํด์ผ ํ๋ค.
์ฆ, ์ฌ์ฉํ ๊ฐ์ฒด๋ฅผ ๋งค๋ฒ new
๋ก ๋ง๋๋ ๊ฒ ๋ณด๋ค, ํ ๋ฒ๋ง ๋ง๋ค์ด์ ์คํ๋ง ์ปจํ
์ด๋์ ๋ฑ๋กํด ๋๋ ๊ฒ์ด ๋ ํจ์จ์ ์ด๋ค.
๋, ์คํ๋ง ์ปจํ ์ด๋์ ๋ฑ๋กํด ๋๋ฉด ์คํ๋ง์์ ์ ๊ณตํ๋ ์ฌ๋ฌ ๊ธฐ๋ฅ๋ค๋ ์ฌ์ฉํ ์ ์๋ค.
@Autowired
: ์์ฑ์์ ์ ์ธ๋๋ฉด, ๊ฐ์ฒด ์์ฑ ์์ ์ ์์ฑ์์ ํ์ํ ๊ฐ์ฒด๋ฅผ ์คํ๋ง ์ปจํ ์ด๋์ ๋ฑ๋ก๋ ์คํ๋ง ๋น ์ค์์ ์ฐพ์์ ๋ฃ์ด ์ค๋ค.- DI (Dependency Injection, ์์กด์ฑ ์ฃผ์ ) : ๊ฐ์ฒด ์์กด๊ด๊ณ๋ฅผ ์ธ๋ถ์์ ๋ฃ์ด ์ฃผ๋ ๊ฒ. ์คํ๋ง์ด ๊ฐ์ฒด๋ฅผ ๋ฃ์ด ์ฃผ๊ณ ์๋ค.
๊ทธ๋ฌ๋ ๊ทธ๋ฅ @Autowired
๋ฅผ ์ ์ธํ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒ์ด๋ค.
์? ์คํ๋ง ์ปจํ ์ด๋๋ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋ก๋์ด ์์ง ์์ ๋์์ ์ฐพ์ ์ ์๊ธฐ ๋๋ฌธ.
๋ฐ๋ผ์ ํ์ ์๋น์ค MemberService
ํด๋์ค์๋ @Service
์ด๋
ธํ
์ด์
์ ์ถ๊ฐํด์ผ ํ๋ค.
ํ์ ์ ์ฅ์์ ๊ตฌํ์ฒด MemoryMemberRepository
ํด๋์ค์๋ @Repository
์ด๋
ธํ
์ด์
์ ์ถ๊ฐํด์ผ ํ๋ค.
์ปจํธ๋กค๋ฌ, ์๋น์ค, ๋ฆฌํฌ์งํ ๋ฆฌ
''์ปจํธ๋กค๋ฌ, ์๋น์ค, ๋ฆฌํฌ์งํ ๋ฆฌ''
์ด ์ธ ์์๋ ์ ํํ๋ ํจํด์ด๊ธฐ ๋๋ฌธ์ ์คํ๋ง์์ ์ด๋ ธํ ์ด์ ์ ์ ๊ณตํ๋ค.
@Controller
: ์ธ๋ถ ์์ฒญ์ ๋ฐ๋๋ค.@Service
: ๋น์ฆ๋์ค ๋ก์ง์ ๋ง๋ค๊ณ ์ํํ๋ค.@Repository
: ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ค.
ํ์ฌ ์ํฉ์์ MemberController๋ MemberService์, MemberService๋ MemberRepository์ ์์กดํด์ผ ํ๋ค.
์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํด ์์กด๊ด๊ณ๋ฅผ ๋ง๋ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
MemberController.java
package hello.hellospring.controller; import hello.hellospring.service.MemberService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @Controller public class MemberController { private final MemberService memberService; @Autowired public MemberController(MemberService memberService) { this.memberService = memberService; } }
MemberService.java
package hello.hellospring.service; import hello.hellospring.domain.Member; import hello.hellospring.repository.MemberRepository; import hello.hellospring.repository.MemoryMemberRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Optional; @Service public class MemberService { private final MemberRepository memberRepository; @Autowired public MemberService(MemberRepository memberRepository) { this.memberRepository = memberRepository; } // codes ... }
MemoryMemberRepository.java
(MemberRepository
์ ๊ตฌํ์ฒด)package hello.hellospring.repository; import hello.hellospring.domain.Member; import org.springframework.stereotype.Repository; import java.util.*; @Repository public class MemoryMemberRepository implements MemberRepository{ // codes ... }
์คํ๋ง ๋น์ ๋ฑ๋กํ๋ 2๊ฐ์ง ๋ฐฉ๋ฒ
์คํ๋ง์ ์ฌ์ฉํ ๋๋ ์ฌ๋งํ ๊ฐ์ฒด๋ ์ ๋ถ ์คํ๋ง ๋น์ผ๋ก ๋ง๋ค์ด ๋ฑ๋กํด ์ฌ์ฉํ๋ค.
์? ๊ทธ๋ ๊ฒ ํ์ ๋ ์ป๋ ์ด์ ์ด ๋ ๋ง๊ธฐ ๋๋ฌธ.
- ์ปดํฌ๋ํธ ์ค์บ๊ณผ ์๋ ์์กด๊ด๊ณ ์ค์
@Component
์ด๋ ธํ ์ด์ (๋๋@Component
์ด๋ ธํ ์ด์ ์ด ํฌํจ๋ ์ด๋ ธํ ์ด์ )์ด ์์ผ๋ฉด ์คํ๋ง ๋น์ผ๋ก ์๋ ๋ฑ๋ก๋๋ค. (์คํ๋ง์ ์ํด ์ปดํฌ๋ํธ ์ค์บ์ด ๊ฐ๋ฅํ๋ค.)@Controller
,@Service
,@Repository
๋ชจ๋@Component
์ด๋ ธํ ์ด์ ์ด ํฌํจ๋์ด ์๋ค.- ์คํ๋ง์ด
@Component
๋ฅผ ๋ง๋๋ฉด, ํด๋น ๊ฐ์ฒด๋ฅผ ์์ฑํด ์คํ๋ง ์ปจํ ์ด๋์ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํด ๋๋ค. - ์๋ ์์กด๊ด๊ณ :
@Autowired
์ ์ฌ์ฉํด ์คํ๋ง ์ปจํ ์ด๋๋ก๋ถํฐ ์คํ๋ง ๋น์ ๊ฐ์ ธ์ ์ฌ์ฉ.
- ์๋ฐ ์ฝ๋๋ก ์ง์ ์คํ๋ง ๋น ๋ฑ๋กํ๊ธฐ (๋ค์ ์๊ฐ ์์ )
โ ์คํ๋ง์ด ์ปดํฌ๋ํธ ์ค์บ์ ํ ๋๋ ์คํํ ์ ์๋ ํด๋์ค(
@SpringBootApplication
)์ ํจํค์ง ๋ฐ ํ์ ํจํค์ง ์ ํ์ผ๋ค๋ง ์ค์บํ๋ค. ๋ค๋ฅธ ํจํค์ง์ ํ์ผ์ ์ปดํฌ๋ํธ ์ค์บ์ ๋์์ด ๋์ง ์๋๋ค.
โ ์คํ๋ง์ ์คํ๋ง ์ปจํ ์ด๋์ ์คํ๋ง ๋น์ ๋ฑ๋กํ ๋, ๊ธฐ๋ณธ์ผ๋ก ์ฑ๊ธํค์ผ๋ก ๋ฑ๋กํ๋ค (= ์ ์ผํ๊ฒ ํ๋๋ง ๋ฑ๋กํ๊ณ , ๊ทธ๊ฒ์ ๊ณต์ ํด ์ฌ์ฉํ๋ค). ๋ฐ๋ผ์ ๊ฐ์ ์คํ๋ง ๋น์ด๋ฉด ๋ชจ๋ ๊ฐ์ ์ธ์คํด์ค๋ค.
(ํน๋ณํ ๊ฒฝ์ฐ์๋ ๋ณ๋ ์ค์ ์ ํตํด ์ฑ๊ธํค์ด ์๋๊ฒ ๋ฑ๋ก๋๋๋ก ํ ์ ์๋ค.)
์๋ฐ ์ฝ๋๋ก ์ง์ ์คํ๋ง ๋น ๋ฑ๋กํ๊ธฐ
์ ๋ฒ ์๊ฐ๊ณผ ๋ค๋ฅด๊ฒ, ์๋ฐ ์ฝ๋๋ก ์ง์ ์คํ๋ง ๋น์ ๋ฑ๋กํ๋ ๋ฐฉ๋ฒ์ ์์๋ณธ๋ค.
@Controller
, @Service
, @Repository
๋ฐ @Autowired
์์ด ์คํ๋ง ๋น์ ๋ฑ๋กํ ์ ์๋ค.
์ง์ ์คํ๋ง ๋น ๋ฑ๋กํ๊ธฐ
์ปจํธ๋กค๋ฌ, ์๋น์ค, ๋ฆฌํฌ์งํ ๋ฆฌ๋ค์ ์์ฐ๋ฅด๋ ํจํค์ง์ SpringConfig.java
๋ฅผ ๋ง๋ค๊ณ ํด๋น ํด๋์ค๋ฅผ @Configuration
์ผ๋ก ์ ์ธํ๋ค.
๊ทธ๋ฆฌ๊ณ ๋ฑ๋กํ ์ธ์คํด์ค๋ฅผ @Bean
์ผ๋ก ์ ์ธํด ์คํ๋ง ๋น์ ๋ฑ๋กํ๋ค.
package hello.hellospring;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
import hello.hellospring.service.MemberService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
}
๋ฉ์๋์ ๋ฆฌํด ๊ฐ์ฒด๋ค์ด ์คํ๋ง ๋น์ผ๋ก ์คํ๋ง ์ปจํ ์ด๋์ ๋ฑ๋ก๋๋ค.
new MemberService(memberRepository())
MemberService์ ๊ฒฝ์ฐ memberRepository()์์ ๋ฑ๋ก๋ MemoryMemberRepository๋ฅผ ์ฌ์ฉํ๋ค.
์ฆ, ์คํ๋ง ๋น์ ๋ฑ๋ก๋ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด๋ฏ๋ก
@Autowired
์ ๊ฐ์ ๊ธฐ๋ฅ์ ํ๋ค.์ปดํฌ๋ํธ์ ๊ฒฝ์ฐ์๋ ์ง์ ๋ฑ๋กํ๊ธฐ๋ณด๋ค
@Component
์@Autowired
๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ซ๋ค.
(์ฐธ๊ณ ) ๊ณผ๊ฑฐ์๋ ์คํ๋ง ๋น์ xml๋ฌธ์๋ก ์ค์ ํ์ผ๋, ์ง๊ธ์ ๊ฑฐ์ ์๋ฐ ์ฝ๋๋ก๋ง ์ค์ ํ๋ฏ๋ก ์ค๋ช ์ ์๋ตํ๋ค.
DI ๋ฐฉ์
DI (์์กด๊ด๊ณ ์ฃผ์ )์๋ ''ํ๋ ์ฃผ์ , setter ์ฃผ์ , ์์ฑ์ ์ฃผ์ '' ์ 3๊ฐ์ง ๋ฐฉ์์ด ์๋ค.
@Controller
public class MemberController {
// ํ๋ ์ฃผ์
๋ฐฉ์
@Autowired private final MemberService memberService;
// setter ์ฃผ์
๋ฐฉ์
@Autowired
public void setMemberService(MemberService memberService) {
this.memberService = memberService
}
// ์์ฑ์ ์ฃผ์
๋ฐฉ์
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
- ํ๋ ์ฃผ์
๋ฐฉ์
- ๋ณ๊ฒฝ์ ์ ์ฐํ์ง ๋ชปํ๋ค๋ ๋จ์ ์ด ์๋ค.
- setter ์ฃผ์
๋ฐฉ์
- setter๊ฐ public์ด์ด์ผ ํ๋ค๋ ํน์ง ๋๋ฌธ์ ์ธ๋ถ์ ๋ ธ์ถ๋๋ค๋ ๋จ์ ์ด ์๋ค.
- ์์ฑ์ ์ฃผ์
๋ฐฉ์
- ์คํ๋ง ์ปจํ ์ด๋์์ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์กฐ๋ฆฝ๋๋ ์์ ์, ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ฉฐ ํ ๋ฒ ์ฃผ์ ํ๋ค.
- ๊ฐ์ฒด ์์ฑ ์์ ์ด์ธ์ ๋ณ๊ฒฝํ ์ ์๋๋ก ๋ง์ ์ ์๋ค.
๊ฒฐ๋ก : DI์๋ ์์ฑ์ ์ฃผ์ ๋ฐฉ์์ ๊ถ์ฅํ๋ค.
์ปดํฌ๋ํธ ์ค์บ ์ฌ์ฉํ๊ธฐ vs ์๋ฐ ์ฝ๋๋ก ์ง์ ์คํ๋ง ๋น ๋ฑ๋กํ๊ธฐ
์ค๋ฌด์์๋ ์ฃผ๋ก ์ ํํ๋ ์ปจํธ๋กค๋ฌ/์๋น์ค/๋ฆฌํฌ์งํ ๋ฆฌ์ ๊ฒฝ์ฐ ์ปดํฌ๋ํธ ์ค์บ์ ์ฌ์ฉํ๊ณ , ์ ํํ๋์ง ์์ ์ฝ๋๋ ์ํฉ์ ๋ฐ๋ผ ๊ตฌํ ํด๋์ค๋ฅผ ๋ณ๊ฒฝํด์ผ ํ ๋ ์ค์ ์ ํตํด ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ๋ค.
์ํฉ์ ๋ฐ๋ผ ๊ตฌํ ํด๋์ค๋ฅผ ๋ณ๊ฒฝํด์ผ ํ ๋ : ์ฐ๋ฆฌ๊ฐ ๊ฐ์ ํ ๊ฒ์ฒ๋ผ '์์ง ๋ฐ์ดํฐ ์ ์ฅ์๊ฐ ์ ์ ๋์ง ์์'๊ฒฝ์ฐ, ์คํ๋ง ๋น์ ์ค์ ํ์ผ๋ก ์ง์ ๋ฑ๋กํ๋ ๊ฒ์ด ๋ซ๋ค.
(๋์ค์ ๋ฐ์ดํฐ ์ ์ฅ์๊ฐ ์ ์ ๋๋ฉด ๊ทธ ๋ถ๋ถ์ ์ค์ ํ์ผ๋ง ๋ฐ๊พธ๋ฉด ๋๊ธฐ ๋๋ฌธ)
@Autowired
๋ฅผ ํตํ DI๋ ์คํ๋ง์ด ๊ด๋ฆฌํ๋ ๊ฐ์ฒด์์๋ง ๋์ํ๋ค.- = ์คํ๋ง ์ปจํ
์ด๋์ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ ๊ฐ์ฒด์ ๋ํด์๋ง
@Autowired
๊ฐ ๋์ํ๋ค.
- = ์คํ๋ง ์ปจํ
์ด๋์ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ ๊ฐ์ฒด์ ๋ํด์๋ง