# Spring / ์˜์กด๊ด€๊ณ„ ์ฃผ์ž… - @Autowired ์˜ต์…˜ ์ฒ˜๋ฆฌ, ์ƒ์„ฑ์ž ์ฃผ์ž… ์‚ฌ์šฉ ๊ถŒ์žฅ
Study Repository

Spring / ์˜์กด๊ด€๊ณ„ ์ฃผ์ž… - @Autowired ์˜ต์…˜ ์ฒ˜๋ฆฌ, ์ƒ์„ฑ์ž ์ฃผ์ž… ์‚ฌ์šฉ ๊ถŒ์žฅ

by rlaehddnd0422

@Autowired ์˜ต์…˜ ์ฒ˜๋ฆฌ

์˜์กด๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•  ์Šคํ”„๋ง ๋นˆ์ด ์—†์–ด๋„ @Autowired๊ฐ€ ๋™์ž‘ํ•ด์•ผ ํ•  ๋•Œ๊ฐ€ ์žˆ๋‹ค.

 

package tmp;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MyService {

    MyRepository myRepository;

    @Autowired
    public MyService(MyRepository myRepository)
    {
        this.myRepository = myRepository;
    }
}

์˜ˆ๋ฅผ๋“ค์–ด, ์œ„์™€ ๊ฐ™์€ Service์™€ Repository ํด๋ž˜์Šค๊ฐ€ ์žˆ๊ณ  Service๊ฐ€ Repository๋ฅผ ์˜์กดํ•˜๊ณ  Repository๋Š” ๋นˆ์œผ๋กœ ๋“ฑ๋ก๋˜์–ด ์žˆ์ง€ ์•Š์€ ์ƒํ™ฉ์ด ์žˆ๋‹ค๊ณ  ํ•ด๋ณด์ž.

 

1. MyService ํด๋ž˜์Šค์— @Component๋ฅผ ๋ถ™์—ฌ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•ด์ฃผ์—ˆ๊ณ , MyRepository๋Š” ๋นˆ์œผ๋กœ ๋“ฑ๋ก๋˜์–ด ์žˆ์ง€ ์•Š์€ ์ผ๋ฐ˜ ์ž๋ฐ” ํด๋ž˜์Šค์ด๋‹ค.

2. MyService๋Š” MyRepository๋ฅผ ์˜์กดํ•˜๋Š” ๊ฐ์ฒด๋กœ @Autowired๋ฅผ ๋ถ™์—ฌ MyService์˜ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์ฃผ์ž…๋ฐ›๋„๋ก ํ–ˆ๋‹ค.

 

-> ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋ก๋˜์–ด ์žˆ์ง€ ์•Š์€ ํด๋ž˜์Šค๋Š” @Autowired๋ฅผ ์‚ฌ์šฉํ•ด๋„ ์˜์กด๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•  ์ˆ˜ ์—†๋‹ค.

 

์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์„ธ ๊ฐ€์ง€ ๋ฐฉ์‹์˜ ์˜ต์…˜์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

1. @Autowired(required = false) : ์ž๋™ ์ฃผ์ž…ํ•  ๋Œ€์ƒ์ด ์—†์œผ๋ฉด ์ˆ˜์ •์ž(setter) ๋ฉ”์†Œ๋“œ ์ž์ฒด๊ฐ€ ํ˜ธ์ถœ์ด ์•ˆ๋จ

2. @Nullable : ์ž๋™ ์ฃผ์ž…ํ•  ๋Œ€์ƒ์ด ์—†์œผ๋ฉด null์ด ์ž…๋ ฅ๋จ

3. Optional<> : ์ž๋™ ์ฃผ์ž…ํ•  ๋Œ€์ƒ์ด ์—†์œผ๋ฉด Optional.empty๊ฐ€ ์ž…๋ ฅ๋จ

 

 

TestCode

package hello.core.AutoWiredTest;

import hello.core.AppConfig;
import hello.core.member.Member;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.lang.Nullable;

import java.util.Optional;

public class AutowiredTest {

    @Test
    void AutowiredOption()
    {
        ApplicationContext ac = new AnnotationConfigApplicationContext(TestBean.class);
    }
	
    
    // Member๋Š” ์Šคํ”„๋ง bean์ด ์•„๋‹Œ ์ผ๋ฐ˜ ์ž๋ฐ” ํด๋ž˜์Šค !
    
    static class TestBean{

        @Autowired(required = false)
        public void setNoBean1(Member member)
        {
            System.out.println("member = " + member);
        }

        @Autowired
        public void setNoBean2(@Nullable Member member)
        {
            System.out.println("member = " + member);
        }

        @Autowired
        public void setNoBean3(Optional<Member> member)
        {
            System.out.println("member = " + member);
        }



    }
}

โ—๏ธ์ฐธ๊ณ  : Optional, @Nullable์€ ์Šคํ”„๋ง ์ „๋ฐ˜์— ๊ฑธ์ณ ์ง€์›๋œ๋‹ค.

 


@Autowired๋Š” ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜์ž.

๊ณผ๊ฑฐ์—๋Š” ์ˆ˜์ •์ž ์ฃผ์ž…๊ณผ ํ•„๋“œ ์ฃผ์ž…์„ ๋งŽ์ด ์‚ฌ์šฉํ–ˆ์ง€๋งŒ, ์ตœ๊ทผ์—๋Š DIํ”„๋ ˆ์ž„์›Œํฌ ๋Œ€๋ถ€๋ถ„์—์„œ ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ๊ถŒ์žฅํ•œ๋‹ค.

 

์ƒ์„ฑ์ž ์ฃผ์ž…์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ์ด์œ 

 

๋ถˆ๋ณ€ ์œ ๋„ 

1. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘๋ถ€ํ„ฐ ์ข…๋ฃŒ๊นŒ์ง€ ์˜์กด๊ด€๊ณ„๊ฐ€ ๋ฐ”๋€”์ผ์ด ์—†๋‹ค. ์˜คํžˆ๋ ค ์˜์กด๊ด€๊ณ„๋Š” ์ข…๋ฃŒ ์ „๊นŒ์ง€ ๋ฐ”๋€Œ๋ฉด ์•ˆ๋œ๋‹ค.

2. ์ˆ˜์ •์ž ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜๋ฉด setter ๋ฉ”์†Œ๋“œ๋ฅผ public์œผ๋กœ ์—ด์–ด๋‘์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋กœ ์ธํ•ด ์‹ค์ˆ˜๋กœ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜๋„ ์žˆ์–ด ์ข‹์€ ์„ค๊ณ„ ๋ฐฉ๋ฒ•์ด ์•„๋‹˜.

3. ์ƒ์„ฑ์ž ์ฃผ์ž…์€ ๊ฐ์ฒด ์ƒ์„ฑ์‹œ ๋”ฑ 1๋ฒˆ ํ˜ธ์ถœ๋˜๋ฏ€๋กœ ๋ถˆ๋ณ€ํ•˜๊ฒŒ ์„ค๊ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

๋ˆ„๋ฝ ๋ฐฉ์ง€ 

ํ”„๋ ˆ์ž„์›Œํฌ ์—†์ด ์ˆœ์ˆ˜ํ•œ ์ž๋ฐ” ์ฝ”๋“œ๋กœ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ํ•  ๋•Œ,

 

์ˆ˜์ •์ž(setter) ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ ๊ฒฝ์šฐ

  public class OrderServiceImpl implements OrderService {
      // ์ˆ˜์ •์ž ์ผ์œผ๋ฏ€๋กœ final ๋บŒ 
      private MemberRepository memberRepository;
      private DiscountPolicy discountPolicy;
      
      @Autowired
      public void setMemberRepository(MemberRepository memberRepository) {
          this.memberRepository = memberRepository;
      }
      
      @Autowired
      public void setDiscountPolicy(DiscountPolicy discountPolicy) {
          this.discountPolicy = discountPolicy;
      }
//...
}

์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ํ•  ๋•Œ๋Š” @Autowired๊ฐ€ ํ”„๋ ˆ์ž„์›Œํฌ ์•ˆ์—์„œ ๋™์ž‘ํ•  ๋•Œ๋Š” ์˜์กด๊ด€๊ณ„๊ฐ€ ์—†์œผ๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€๋งŒ, ์ˆœ์ˆ˜ ์ž๋ฐ”์ฝ”๋“œ ํ…Œ์ŠคํŠธ์˜ ๊ฒฝ์šฐ์—๋Š” ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.

class OrderServiceImpTest {

    @Test
    void createOrder()
    {
        OrderServiceImp orderService =new OrderServiceImp();
        orderService.createOrder(1L,"ItemA",1000);
    }
}
  • ์‹คํ–‰์€ ๋˜์ง€๋งŒ OrderServiceImp์˜ ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…์ด ๋ˆ„๋ฝ๋˜์–ด NPE๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
  • setter ์ˆ˜์ •์ž ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜๋ฉด ์˜์กด๊ด€๊ณ„ ์ฃผ์ž… ๋ฐ์ดํ„ฐ๊ฐ€ ๋ˆ„๋ฝ๋˜์—ˆ์„ ๋•Œ ์–ด๋–ค ๊ฒŒ ๋ˆ„๋ฝ๋˜์—ˆ๋Š”์ง€ ๋ˆˆ์— ํ™• ๋ณด์ด์ง€ ์•Š๋Š”๋‹ค.
  • ํ•˜์ง€๋งŒ ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜๋ฉด ์˜์กด๊ด€๊ณ„ ์ฃผ์ž… ๋ฐ์ดํ„ฐ๊ฐ€ ๋ˆ„๋ฝ๋˜์—ˆ์„ ๋•Œ ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒ๋˜์–ด ์–ด๋–ค ๊ฐ’์„ ํ•„์ˆ˜๋กœ ์ฃผ์ž…ํ•ด์•ผ ํ•˜๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๋‹ค. 

final ํ‚ค์›Œ๋“œ ์‚ฌ์šฉ

์ƒ์„ฑ์ž ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•„๋“œ์— final ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ž˜์„œ ์ƒ์„ฑ์ž์—์„œ ํ˜น์‹œ๋ผ๋„ ๊ฐ’์ด ์„ค์ •๋˜์ง€ ์•Š๋Š” ์˜ค๋ฅ˜๋ฅผ ์ปดํŒŒ์ผ ์‹œ์ ์—์„œ ๋ฐœ์ƒ์‹œ์ผœ์ค€๋‹ค.

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

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

์ž˜ ๋ณด๋ฉด ํ•„์ˆ˜ ํ•„๋“œ์ธ discountPolicy ์— ๊ฐ’์„ ์„ค์ •ํ•ด์•ผ ํ•˜๋Š”๋ฐ, ์ด ๋ถ€๋ถ„์ด ๋ˆ„๋ฝ๋˜์—ˆ๋‹ค. ์ž๋ฐ”๋Š” ์ปดํŒŒ์ผ ์‹œ์ ์— ๋‹ค์Œ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

java: variable discountPolicy might not have been initialized

์ปดํŒŒ์ผ ์˜ค๋ฅ˜๋Š” ์„ธ์ƒ์—์„œ ๊ฐ€์žฅ ๋น ๋ฅด๊ณ , ์ข‹์€ ์˜ค๋ฅ˜๋‹ค. 

 

 

<์ •๋ฆฌ>

  • ์ƒ์„ฑ์ž ์ฃผ์ž… ๋ฐฉ์‹์€ ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์— ์˜์กดํ•˜์ง€ ์•Š๊ณ , ์ˆœ์ˆ˜ํ•œ ์ž๋ฐ” ์–ธ์–ด์˜ ํŠน์ง•์„ ๊ฐ€์žฅ ์ž˜ ์‚ด๋ฆฌ๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.
  • ๊ธฐ๋ณธ์œผ๋กœ๋Š” ์ƒ์„ฑ์ž ์ฃผ์ž…๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์ž. (์˜ต์…˜์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์ˆ˜์ •์ž ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜์ž)
  • ํ•„๋“œ์ฃผ์ž…์€ ์•ˆ์“ฐ๋Š”๊ฒŒ ์ข‹๋‹ค.

๋กฌ๋ณต ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ ์ตœ์ ํ™”

 

https://rlaehddnd0422.tistory.com/27

 

Spring / ๋กฌ๋ณต ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•œ ์ฝ”๋“œ ์ตœ์ ํ™”

๋กฌ๋ณต ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด getter, setter, tostring ๊ฐ™์€ ๋ฉ”์†Œ๋“œ๋ฅผ ๋”ฐ๋กœ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•„๋„ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ๋ฅผ ๊น”๋”ํ•˜๊ฒŒ ์งค ์ˆ˜ ์žˆ๋‹ค. ๋กฌ๋ณต ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜๋ฐฉ๋ฒ• (IntelliJ IDEA) https://goddaehee.tistory.com/208

rlaehddnd0422.tistory.com

 

๊ธฐ์กด OrderServiceImp

@Component
public class OrderServiceImp implements OrderService {
    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;
    
    @Autowired
    public OrderServiceImp(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }

์ƒ์„ฑ์ž๊ฐ€ ํ•˜๋‚˜ ๋ฟ์ผ๋•Œ์—๋Š” @Autowired ์ƒ๋žตํ•ด๋„ ๋œ๋‹ค.

 

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

    public OrderServiceImp(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }

 

๋กฌ๋ณต ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ ์šฉํ•œ ์ตœ์ข…๊ฒฐ๊ณผ

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

 

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

 

 


 

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

Study Repository

rlaehddnd0422

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