# Spring / ์ง€๊ธˆ๊นŒ์ง€ ์‚ฌ์šฉํ•œ ์–ด๋…ธํ…Œ์ด์…˜ ์ •๋ฆฌ @
Study Repository

Spring / ์ง€๊ธˆ๊นŒ์ง€ ์‚ฌ์šฉํ•œ ์–ด๋…ธํ…Œ์ด์…˜ ์ •๋ฆฌ @

by rlaehddnd0422

์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

์‚ฌ์ „์  ์˜๋ฏธ๋กœ ์ฃผ์„์„ ๋œปํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์„ ์ฃผ์„๊ณผ๋Š” ์—ญํ• ์ด ๋‹ค๋ฅด์ง€๋งŒ, ์ฃผ์„์ฒ˜๋Ÿผ ๋‹ฌ์•„ ํŠน์ˆ˜ํ•œ ์˜๋ฏธ๋ถ€์—ฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๊ณ , ๊ธฐ๋Šฅ ์ฃผ์ž…์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ€์žฅ ํฐ ์ด์œ ๋Š” ํ”„๋กœ๊ทธ๋žจ์—๊ฒŒ ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ๋ฅผ ์œ„ํ•ด์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

@Controller

์ปจํŠธ๋กค๋Ÿฌ ๋กœ์ง์ž„์„ ์•Œ๋ ค์ฃผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜

 

@Service 

์„œ๋น„์Šค ๋กœ์ง์ž„์„ ์•Œ๋ ค์ฃผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜

 

@Repository

๋ฆฌํฌ์ง€ํ† ๋ฆฌ ๋กœ์ง์ž„์„ ์•Œ๋ ค์ฃผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜ 

 

@Test

JUnit์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜.

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์ž„์„ ์•Œ๋ ค์ฃผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ์ด ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ์ฝ”๋“œ๋Š” ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

@Responsebody

๊ฐ์ฒด๋ฅผ HTTP์š”์ฒญ์˜ body๋‚ด์šฉ์œผ๋กœ mappingํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ๋กœ ์ „์†ก 

@Responsebody๊ฐ€ ๋ถ™์€ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์žˆ์œผ๋ฉด HTTP ์š”์ฒญ์˜ ๋ฏธ๋””์–ด ํƒ€์ž…๊ณผ ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ํƒ€์ž…์„ ๋จผ์ € ํ™•์ธํ•œ๋‹ค.

์ฆ‰,  @Responsebody ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด http ์š”์ฒญ body๋ฅผ ์ž๋ฐ” ๊ฐ์ฒด๋‚˜ string์œผ๋กœ ์ „๋‹ฌ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

 

@GetMapping

์ฃผ์–ด์ง„ URI ํ‘œํ˜„์‹๊ณผ ์ผ์น˜ํ•˜๋Š” HTTP GET ์š”์ฒญ์ฒ˜๋ฆฌ ํ•ด์ฃผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜

ex) localhost:8080/hello ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด @GetMapping("hello")์ด ๋ถ™์€ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

ex) @GetMapping("/")์ธ ๊ฒฝ์šฐ ํ™ˆ ํ™”๋ฉด์— ๋งคํ•‘๋จ.

 

@PostMapping 

: ์ฃผ์–ด์ง„ URI ํ‘œํ˜„์‹๊ณผ ์ผ์น˜ํ•˜๋Š” HTTP POST ์š”์ฒญ์ฒ˜๋ฆฌ ํ•ด์ฃผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜

 

@RequestMapping

์ฃผ์–ด์ง„ URIํ‘œํ˜„์‹๊ณผ ์ผ์น˜ํ•˜๋Š” HTTP Request ๋ฅผ ์š”์ฒญ์ฒ˜๋ฆฌ ํ•ด์ฃผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜

 

 

@Override

๋ถ€๋ชจ๋‚˜ ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„ ํด๋ž˜์Šค์—์„œ ๋ฉ”์†Œ๋“œ ๊ตฌํ˜„ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜

 

@BeforeEach

๊ฐ ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์ „์— ํ˜ธ์ถœ๋˜๋„๋ก ํ•ด์ฃผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜.

ํ…Œ์ŠคํŠธ๊ฐ€ ์„œ๋กœ ์˜ํ–ฅ์ด ์—†๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ดใ…” ํ•ญ์ƒ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ์˜์กด๊ด€๊ณ„๋ฅผ ์ƒˆ๋กœ ๋งบ์–ด์ฃผ๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

 

@AfterEach  

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜.

ํ•œ ๋ฒˆ์— ์—ฌ๋Ÿฌ ๋ฉ”์†Œ๋“œ์˜ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ DB์— ์ง์ „ ํ…Œ์ŠคํŠธ์˜ ๊ฒฐ๊ณผ๊ฐ€ ๋‚จ์•„ ์ด์ „ ํ…Œ์ŠคํŠธ๊ฐ€ ๋‹ค์Œ ํ…Œ์ŠคํŠธ์— ์˜ํ–ฅ์„ ๋ผ์ณ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๊ฐ€ ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

@AfterEach๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ ํ…Œ์ŠคํŠธ๊ฐ€ ๋๋‚˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋น„์šฐ๋Š” ์ž‘์—…์„ ๊ตฌํ˜„ํ•˜๋ฉด ์ด์ „ ํ…Œ์ŠคํŠธ๊ฐ€ ๋‹ค์Œ ํ…Œ์ŠคํŠธ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

@Autowired 

์ž๋™ ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…(DI) ์–ด๋…ธํ…Œ์ด์…˜.

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋ก๋œ ๋นˆ์„ ์ฐพ์•„์„œ ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…(Dependency Injection, DI) ํ•ด์ค๋‹ˆ๋‹ค.

์ƒ์„ฑ์ž๊ฐ€ ํ•˜๋‚˜์ผ ๊ฒฝ์šฐ ์ƒ๋žตํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค.

 

@Configuration

์ˆ˜๋™ ๋นˆ ๊ด€๋ฆฌ ํด๋ž˜์Šค์ž„์„ ์•Œ๋ ค์ฃผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜.

CGLIB ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋ฐ”์ดํŠธ์ฝ”๋“œ ์กฐ์ž‘์„ ํ†ตํ•ด ๋นˆ๋“ค์˜ ์‹ฑ๊ธ€ํ†ค์„ ๋ณด์žฅํ•ด์ค๋‹ˆ๋‹ค.

 

@Bean

์ˆ˜๋™ ๋นˆ ๊ด€๋ฆฌ ํด๋ž˜์Šค์—์„œ ์ˆ˜๋™์œผ๋กœ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜.

 

@ComponentScan

@Component ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ํด๋ž˜์Šค๋ฅผ ์Šค์บ”ํ•ด์„œ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.

 

@Configuration
@ComponentScan(
        excludeFilters = @ComponentScan.Filter(type= FilterType.ANNOTATION, classes = Configuration.class)
)
public class AutoAppConfig {

}

ํŒŒ๋ผ๋ฏธํ„ฐ exlucdeFilters, includeFilters, basePackages ๋กœ ์ œ์™ธ, ํฌํ•จ, ์‹œ์ž‘์œ„์น˜ ์ง€์ • ๊ฐ€๋Šฅ 

๊ธฐ๋ณธ ์ ์šฉ ๋Œ€์ƒ : @Controller, @Service, @Repository, @Configuration

 

@Component

์ž๋™ ์Šคํ”„๋ง ๋นˆ ๋“ฑ๋ก ์–ด๋…ธํ…Œ์ด์…˜.

ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ํด๋ž˜์Šค๋Š” ์ž๋™์œผ๋กœ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋ก๋ฉ๋‹ˆ๋‹ค. 

 

@Transaction

ํ…Œ์ŠคํŠธ ์ง„ํ–‰ ์ „์— DB์— ๋Œ€ํ•œ ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•˜๊ณ , ํ…Œ์ŠคํŠธ ์™„๋ฃŒ ํ›„์—๋Š” ํ•ญ์ƒ ๋กค๋ฐฑ์„ ์ง„ํ–‰ํ•˜์—ฌ DB์— ๋ฐ์ดํ„ฐ๊ฐ€ ๋‚จ์ง€ ์•Š๋„๋ก ํ•ด์„œ ๋‹ค์Œ ํ…Œ์ŠคํŠธ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

 

@SpringBootTest

ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ํ™˜๊ฒฝ์„ ์ค€๋น„ํ•ด์ค๋‹ˆ๋‹ค. ๋ชจ๋“  ๋นˆ๋“ค์„ ์Šค์บ”ํ•˜๊ณ  ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์™€ ํ…Œ์ŠคํŠธ๋ฅผ ํ•จ๊ป˜ ์‹คํ–‰ํ•˜๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค.

 

@Displayname

JUnit์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ @Test์˜ ํ•จ์ˆ˜๋ช…์„ ๋ณ€๊ฒฝํ•ด์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@Test
@DisplayName("๊ตฌ์ฒด ํƒ€์ž…์œผ๋กœ ์กฐํšŒ")
void findBeanByName2()
{
    MemberService memberService = ac.getBean("memberService", MemberServiceImp.class);
    Assertions.assertThat(memberService).isInstanceOf(MemberServiceImp.class);
}

 

@RequiredArgsConstructor

final์ด ๋ถ™์€ ํ•„๋“œ๋ฅผ ๋ชจ์•„ ์ƒ์„ฑ์ž๋ฅผ ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด ์ค€๋‹ค. ( ์ฝ”๋“œ์—๋Š” ๋ณด์ด์ง€ ์•Š์Œ )

@Component
@RequiredArgsConstructor
public class OrderServiceImp implements OrderService {
    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;

 

@Qualifier

๊ฐ™์€ ํƒ€์ž…์œผ๋กœ ๋“ฑ๋ก๋œ ๋นˆ์ด ๋‘ ๊ฐœ ์ด์ƒ์ผ ๋•Œ, ์ถ”๊ฐ€ ๊ตฌ๋ถ„์ž๋ฅผ ํ†ตํ•ด ์˜์กด๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•ด์ฃผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜.

@Component
@Qualifier("mainDp")
public class FixDiscountPolicy implements DiscountPolicy{
@Component
@Qualifier("secondDp")
public class RateDiscountPolicy implements DiscountPolicy{
@Component
public class OrderServiceImp implements OrderService {
    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;

    @Autowired
    public OrderServiceImp(MemberRepository memberRepository, @Qualifier("mainDp") DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }

@Qualifier ๋ผ๋ฆฌ ๋งค์นญ -> ๋งŒ์•ฝ ์—†๋‹ค ? -> ๋นˆ์ด๋ฆ„ ๋งค์นญ -> ๋“ฑ๋ก๋œ ๋นˆ์—๋„ ์—†๋‹ค? -> NoSuchBeanDefinitionException ์˜ˆ์™ธ ๋ฐœ์ƒ

 

 

@Primary

์šฐ์„ ์ˆœ์œ„๋ฅผ ์ง€์ •ํ•ด์ฃผ๋Š” ์ง€์ •์ž๋กœ ์šฐ์„  ์˜์กด๊ถŒ์„ ๊ฐ–๋Š” ๋นˆ์—๊ฒŒ @Primary๋ฅผ ๋ถ™ํ˜€์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

@Component
@Primary
@Qualifier("mainDp")
public class FixDiscountPolicy implements DiscountPolicy{

 

@Primary์™€ @Qualifier์ค‘์—์„œ๋Š” @Qualifier๊ฐ€ ์šฐ์„ ๊ถŒ์ด ๋†’์Šต๋‹ˆ๋‹ค.

 

 

@PostConstructor

์ƒ์„ฑ์ž๊ฐ€ ์‹คํ–‰๋œ ์ดํ›„์— ๊ฐ์ฒด๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ์ž‘์—…์„ ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜.

 

@PreDestroy

์†Œ๋ฉธ์ž๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ด์ „์— ์‹คํ–‰ํ•˜๋Š” ๋ฉ”์†Œ๋“œ์ž„์„ ์•Œ๋ ค์ฃผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜. 

 

@Scope

๋นˆ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ์„ค์ •ํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ๋นˆ ์Šค์ฝ”ํ”„๋กœ๋Š” singleton๊ณผ prototype์ด ์žˆ๋‹ค.

singleton์˜ ๊ฒฝ์šฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ข…๋ฃŒ์ง์ „๊นŒ์ง€ ์œ ์ง€๋˜์ง€๋งŒ,

prototype์˜ ๊ฒฝ์šฐ ๋นˆ์˜ ์ƒ์„ฑ-> ์˜์กด๊ด€๊ณ„ ์ฃผ์ž… ๊นŒ์ง€๋งŒ ์œ ์ง€๋œ๋‹ค. (ํด๋ผ์ด์–ธํŠธ์— ๋ฆฌํ„ด๋˜๊ณ  ์†Œ๋ฉธ๋จ)

์›น ์Šค์ฝ”ํ”„๋กœ๋Š” request, session ๋“ฑ์ด ์žˆ์Œ.

 

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

Study Repository

rlaehddnd0422

ํ™œ๋™ํ•˜๊ธฐ