/* ์ด ๊ธ์ ๊น์ํ๋์ ๊ฐ์๋ฅผ ๋ณด๊ณ ์ ๋ฆฌํ๋ ค๊ณ ์์ฑํ ๊ธ์ ๋๋ค.
๊ฐ์ธ์ ์ธ ๊ณต๋ถ๋ฅผ ์ํด ์ฌ๋ฆฌ๋ ๊ธ์ด๋ฏ๋ก ์ค๊ฐ ์ค๊ฐ ์ฝ๋๋ ์๋ต๋์์ต๋๋ค. */
์ต์ ์ฒ๋ฆฌ
- ์ฃผ์ ํ ์คํ๋ง ๋น์ด ์์ด๋ ๋์ํด์ผ ํ ๋๊ฐ ์๋ค.
(๊ทธ๋ฐ๋ฐ '@Autowired'๋ง ์ฌ์ฉํ๋ฉด 'required' ์ต์ ๊ธฐ๋ณธ๊ฐ์ด 'true'๋ก ๋์ด์์ด์ ์๋์ฃผ์ ๋์์ด ์์ผ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํจ)
1. ์๋ ์ฃผ์ ์ต์ ์ฒ๋ฆฌ ๋ฐฉ๋ฒ
(์ฌ๊ธฐ์ Member๋ ์คํ๋ง ๋น์ด ์๋)
โ `@Autowired(required = false)`
static class TestBean {
@Autowired(required = false)
public void setNoBean1(Member noBean1) {
System.out.println("noBean1 = " + noBean1);
}
}
: ์๋ ์ฃผ์ ํ ๋์์ด ์์ผ๋ฉด ์์ ์ ๋ฉ์๋ ์์ฒด๊ฐ ํธ์ถ์ด ์๋จ
โก `@Nullable`
static class TestBean {
@Autowired
public void setNoBean2(@Nullable Member noBean2) {
System.out.println("noBean2 = " + noBean2);
}
}
: ์๋ ์ฃผ์ ํ ๋์์ด ์์ผ๋ฉด null์ด ์ ๋ ฅ๋จ
โข `Optional<>`
static class TestBean {
@Autowired
public void setNoBean3(Optional<Member> noBean3) {
System.out.println("noBean3 = " + noBean3);
}
}
: ์๋ ์ฃผ์ ํ ๋์์ด ์์ผ๋ฉด Optional.empty ๊ฐ ์ ๋ ฅ๋จ
์์ฑ์ ์ฃผ์ ์ ์ ํํด๋ผ!
- ์ต๊ทผ์ ์คํ๋ง์ ํฌํจํ DI ํ๋ ์์ํฌ ๋๋ถ๋ถ์ด ์์ฑ์ ์ฃผ์ ์ ๊ถ์ฅํ๋ค. ์ด์ ๋ ๋ค์๊ณผ ๊ฐ๋ค
1. ๋ถ๋ณ
โ ๋๋ถ๋ถ์ ์์กด๊ด๊ณ ์ฃผ์ ์ ํ ๋ฒ ์ผ์ด๋๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ์ข ๋ฃ ์์ ๊น์ง ์์กด๊ด๊ณ๋ฅผ ๋ณ๊ฒฝํ ์ผ์ด ์๋ค.
์คํ๋ ค ๋๋ถ๋ถ์ ์์กด๊ด๊ณ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ข ๋ฃ ์ ๊น์ง ๋ณํ๋ฉด ์๋๋ค(๋ถ๋ณํด์ผ ํจ)
โ ์์ ์ ์ฃผ์ ์ ์ฌ์ฉํ๋ฉด setXxx ๋ฉ์๋๋ฅผ public ์ผ๋ก ์ด์ด๋์ด์ผ ํจ(๋๊ตฐ๊ฐ๊ฐ ์ค์๋ก ํธ์ถํด์ ๋ณ๊ฒฝ ๊ฐ๋ฅ์ฑ์ด ์์)
โ ๋ณ๊ฒฝํ๋ฉด ์๋๋ ๋ฉ์๋๋ฅผ ์ด์ด๋๋ ๊ฒ์ ์ข์ ์ค๊ณ ๋ฐฉ๋ฒ์ด ์๋
โ ์์ฑ์ ์ฃผ์ ์ ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ ๋ฑ! ํ ๋ฒ๋ง ํธ์ถ๋๋ฏ๋ก ์ดํ์ ํธ์ถ๋๋ ์ผ์ด ์๋ค. ๋ฐ๋ผ์ ๋ถ๋ณํ๊ฒ ์ค๊ณ ๊ฐ๋ฅํ๋ค.
2. ๋๋ฝ
* ์์ ์ ์์กด๊ด๊ณ์ธ ๊ฒฝ์ฐ
OrderServiceImpl
@Component
public class OrderServiceImpl implements OrderService{
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๊ฐ ํ๋ ์์ํฌ ์์์ ๋์ํ ๋๋ ์์กด๊ด๊ณ๊ฐ ์์ผ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง๋ง, ์ง๊ธ์ ํ๋ ์์ํฌ ์์ด ์์ํ ์๋ฐ์ฝ๋๋ก ๋จ์ํ ์คํธ ์ํ
OrderServiceImplTest
class OrderServiceImplTest {
@Test
void createOrder() {
OrderServiceImpl orderService = new OrderServiceImpl();
orderService.createOrder(1L, "itemA", 10000);
}
}
: ์ด๋ ๊ฒ ํ ์คํธ๋ฅผ ์คํํ๋ฉด ์ค๋ฅ๊ฐ ์์ด๋ณด์ด๊ณ ์คํ์ ๋๋ NPE ๋ฐ์
โ memberRepository, discountPolicy ๋ชจ๋ ์์กด๊ด๊ณ ์ฃผ์ ์ด ๋๋ฝ๋์๊ธฐ ๋๋ฌธ. ์ฝ๋๋ฅผ ๊น๋ณด๊ธฐ ์ ์ ์ด๋ค ๋ถ๋ถ์ด ๋๋ฝ๋์๋์ง ์๊ธฐ ํ๋ฆ
* ์์ฑ์ ์ฃผ์ ์ธ ๊ฒฝ์ฐ
OrderServiceImpl
@Component
public class OrderServiceImpl implements OrderService{
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
//....
}
OrderServiceImplTest
: ์์ฑ์์ฃผ์ ์ ์ฌ์ฉํ๋ฉด ์์ฒ๋ผ ์ฃผ์ ๋ฐ์ดํฐ๋ฅผ ๋๋ฝํ์ ๋ ์ปดํ์ผ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉฐ, IDE์์ ๋ฐ๋ก ์ด๋ค ๊ฐ์ ํ์๋ก ์ฃผ์ ํด์ผ ํ๋์ง ์ ์ ์์
3. final ํค์๋ ์ฌ์ฉ
@Component
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
: ์์ฑ์ ์ฃผ์ ์ ์ฌ์ฉํ๋ฉด ํ๋์ final ํค์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
โ ์์ ์ ์ฃผ์ ์ ํฌํจํ ๋๋จธ์ง ์ฃผ์ ๋ฐฉ์์ ๋ชจ๋ ์์ฑ์ ์ดํ์ ํธ์ถ๋๋ฏ๋ก, ํ๋์ final ํค์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
: ํน์๋ผ๋ ๊ฐ์ด ์ค์ ๋์ง ์์ผ๋ ์ค๋ฅ๋ฅผ ์ปดํ์ผ ์์ ์์ ๋ง์์ค๋ค.
( *์ปดํ์ผ ์ค๋ฅ๋ ์ธ์์์ ๊ฐ์ฅ ๋น ๋ฅด๊ณ ์ข์ ์ค๋ฅ๋ค! )
4. ์ ๋ฆฌ
โ ์์ฑ์ ์ฃผ์ ๋ฐฉ์์ ์ ํํ๋ ์ด์ ๋ ์ฌ๋ฌ๊ฐ์ง๊ฐ ์์ง๋ง, ํ๋ ์์ํฌ์ ์์กดํ์ง ์๊ณ , ์์ํ ์๋ฐ ์ธ์ด์ ํน์ง์ ์ด๋ฆฌ๋ ๋ฐฉ๋ฒ์ด๋ค!
โ ๊ธฐ๋ณธ์ผ๋ก ์์ฑ์ ์ฃผ์ ์ ์ฌ์ฉํ๊ณ , ํ์ ๊ฐ์ด ์๋ ๊ฒฝ์ฐ์ ์์ ์ ์ฃผ์ ๋ฐฉ์์ ์ต์ ์ผ๋ก ๋ถ์ฌํ๋ฉด ๋๋ค. ์์ฑ์ ์ฃผ์ ๊ณผ ์์ ์ ์ฃผ์ ์ ๋์์ ์ฌ์ฉํ ์ ์๋ค.