[Spring] 7.๋ค์ํ ์์กด๊ด๊ณ ์ฃผ์ ๋ฐฉ๋ฒ
1. ๋ค์ํ ์์กด๊ด๊ณ ์ฃผ์ ๋ฐฉ๋ฒ
4๊ฐ์ง ๋ฐฉ๋ฒ
1) ์์ฑ์ ์ฃผ์
2) ์์ ์ ์ฃผ์ (setter ์ฃผ์ ) 3) ํ๋ ์ฃผ์ 4) ์ผ๋ฐ ๋ฉ์๋ ์ฃผ์ |
1) ์์ฑ์ ์ฃผ์
- ์์ฑ์ ํธ์ถ ์์ ์ ๋ฑ ํ ๋ฒ๋ง ํธ์ถ๋๋ ๊ฒ์ด ๋ณด์ฅ
- [๋ถ๋ณ / ํ์] ์์กด๊ด๊ณ์ ์ฌ์ฉ
@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;
}
}
* ์ข์ ๊ฐ๋ฐ ์ต๊ด : ์ ์ฝ (์์ฑ์๋ฅผ ํตํด์๋ง ์์กด๊ด๊ณ ์ฃผ์ ๋๋ ๊ฒ์ฒ๋ผ / ์ธ๋ถ ์์ ๋ถ๊ฐ๋ฅํ ๊ฒ์ฒ๋ผ)
์ค์) ์์ฑ์๊ฐ ํ๊ฐ๋ง ์์ผ๋ฉด @Autowired ์๋ต๊ฐ๋ฅ
@Component
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
2) ์์ ์ ์ฃผ์ (setter ์ฃผ์ )
- ํ๋๊ฐ ๋ณ๊ฒฝ ์์ ์ ๋ฉ์๋(setter)๋ฅผ ํตํด์ ์์กด๊ด๊ณ ์ฃผ์ ํ๋ ๋ฐฉ์
- [์ ํ / ๋ณ๊ฒฝ] ๊ฐ๋ฅ์ฑ์๋ ์์กด๊ด๊ณ์ ์ฌ์ฉ
@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 ์ ๊ธฐ๋ณธ ๋์์ ์ฃผ์ ํ ๋์์ด ์์ผ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
์ฃผ์ ํ ๋์์ด ์์ด๋ ๋์ํ๊ฒ ํ๋ ค๋ฉด @Autowired(required = false) ๋ก ์ง์ ํ๋ฉด ๋๋ค.
์ฐธ๊ณ : ์๋ฐ๋น ํ๋กํผํฐ ๊ท์ฝ
์๋ฐ์์๋ ๊ณผ๊ฑฐ๋ถํฐ ํ๋์ ๊ฐ์ ์ง์ ๋ณ๊ฒฝํ์ง ์๊ณ , setXxx, getXxx ๋ผ๋ ๋ฉ์๋๋ฅผ ํตํด์ ๊ฐ์ ์ฝ๊ฑฐ๋ ์์ ํ๋ ๊ท์น
ex)
class Data {
private int age;
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
3) ํ๋ ์ฃผ์
- ํ๋๊ฐ ๋ณ๊ฒฝ ์์ ์ ๋ฉ์๋(setter)๋ฅผ ํตํด์ ์์กด๊ด๊ณ ์ฃผ์ ํ๋ ๋ฐฉ์
- [์ ํ / ๋ณ๊ฒฝ] ๊ฐ๋ฅ์ฑ์๋ ์์กด๊ด๊ณ์ ์ฌ์ฉ
@Component
public class OrderServiceImpl implements OrderService {
@Autowired
private MemberRepository memberRepository;
@Autowired
private DiscountPolicy discountPolicy;
}
ํน์ง
- ์ฝ๋๊ฐ ๊ฐ๊ฒฐํด์ ๋ง์ ๊ฐ๋ฐ์๋ค์ ์ ํนํ์ง๋ง ์ธ๋ถ์์ ๋ณ๊ฒฝ์ด ๋ถ๊ฐ๋ฅํด์ ํ
์คํธ ํ๊ธฐ ํ๋ฆ
- DI ํ๋ ์์ํฌ๊ฐ ์์ผ๋ฉด ์๋ฌด๊ฒ๋ ํ ์ ์๋ค. (์ฌ์ฉx)
[์ด๋ด๋๋ง ์ฌ์ฉ]
์ ํ๋ฆฌ์ผ์ด์
์ ์ค์ ์ฝ๋์ ๊ด๊ณ ์๋ ํ
์คํธ ์ฝ๋
์คํ๋ง ์ค์ ์ ๋ชฉ์ ์ผ๋ก ํ๋ @Configuration ๊ฐ์ ๊ณณ์์๋ง ํน๋ณํ ์ฉ๋๋ก ์ฌ์ฉ
์ฐธ๊ณ :
์์ํ ์๋ฐ ํ ์คํธ ์ฝ๋์๋ ๋น์ฐํ @Autowired๊ฐ ๋์ํ์ง ์๋๋ค.
@SpringBootTest ์ฒ๋ผ ์คํ๋ง ์ปจํ ์ด๋๋ฅผ ํ ์คํธ์ ํตํฉํ ๊ฒฝ์ฐ์๋ง ๊ฐ๋ฅํ๋ค.
์ฐธ๊ณ :
๋ค์ ์ฝ๋์ ๊ฐ์ด @Bean ์์ ํ๋ผ๋ฏธํฐ์ ์์กด๊ด๊ณ๋ ์๋ ์ฃผ์ ๋๋ค.
์๋ ๋ฑ๋ก์ ์๋ ๋ฑ๋ก๋ ๋น์ ์์กด๊ด๊ณ๊ฐ ํ์ํ ๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค
@Bean
OrderService orderService(MemberRepository memberRepoisitory, DiscountPolicy discountPolicy) {
new OrderServiceImpl(memberRepository, discountPolicy)
}
4) ์ผ๋ฐ ์ฃผ์
- ์ผ๋ฐ ๋ฉ์๋๋ฅผ ํตํด์ ์ฃผ์ ๋ฐ์ ์ ์๋ค.
- ํน์ง
> ํ ๋ฒ์ ์ฌ๋ฌ ํ๋๋ฅผ ์ฃผ์ ๋ฐ์ ์ ์๋ค.
> ์ผ๋ฐ์ ์ผ๋ก ์ ์ฌ์ฉํ์ง ์์
@Component
public class OrderServiceImpl implements OrderService {
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired
public void init(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
์ฐธ๊ณ :
์ด์ฉ๋ฉด ๋น์ฐํ ์ด์ผ๊ธฐ์ด์ง๋ง ์์กด๊ด๊ณ ์๋ ์ฃผ์ ์ ์คํ๋ง ์ปจํ ์ด๋๊ฐ ๊ด๋ฆฌํ๋ ์คํ๋ง ๋น์ด์ด์ผ ๋์ํ๋ค.
์คํ๋ง ๋น์ด ์๋ Member ๊ฐ์ ํด๋์ค์์ @Autowired ์ฝ๋๋ฅผ ์ ์ฉํด๋ ์๋ฌด ๊ธฐ๋ฅ๋ ๋์ํ์ง ์๋๋ค.
2. ์ต์ ์ฒ๋ฆฌ
- ์ฃผ์ ํ ์คํ๋ง ๋น์ด ์์ด๋ ๋์ํด์ผํ ๋ ์์
- ๊ทธ๋ฐ๋ฐ @Autowired๋ง ์ฌ์ฉํ๋ฉด 'required' ์ต์ ๊ธฐ๋ณธ๊ฐ์ด 'true' ๋ผ์ ์๋ ์ฃผ์ ๋์์ด ์์ผ๋ฉด ์ค๋ฅ ๋ฐ์
์๋ ์ฃผ์ ๋์์ ์ต์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ
- @Autowired(required=false) : ์๋ ์ฃผ์ ํ ๋์์ด ์์ผ๋ฉด ์์ ์ ๋ฉ์๋ ์์ฒด๊ฐ ํธ์ถ X
- org.springframework.lang.@Nullable : ์๋ ์ฃผ์ ํ ๋์์ด ์์ผ๋ฉด null์ด ์ ๋ ฅ๋จ
- Optional<> : ์๋ ์ฃผ์ ํ ๋์์ด ์์ผ๋ฉด Optional.empty๊ฐ ์ ๋ ฅ๋จ
// ํธ์ถ ์๋จ
@Autowired(required = false)
public void setNoBean1(Member member) {
System.out.println("setNoBean1 = " + member);
}
// null ํธ์ถ
@Autowired
public void setNoBean2(@Nullable Member member) {
System.out.println("setNoBean2 = " + member);
}
// Optional.empty ํธ์ถ
@Autowired(required = false)
public void setNoBean3(Optional<Member> member) {
System.out.println("setNoBean3 = " + member);
}
- Member๋ ์คํ๋ง ๋น์ด ์๋๋ค.
- setNoBean1() ์ @Autowired(required=false) ์ด๋ฏ๋ก ํธ์ถ ์์ฒด๊ฐ ์๋๋ค.
์ฐธ๊ณ :
@Nullable, Optional์ ์คํ๋ง ์ ๋ฐ์ ๊ฑธ์ณ์ ์ง์๋๋ค.
ex) ์์ฑ์ ์๋ ์ฃผ์ ์์ ํน์ ํ๋์๋ง ์ฌ์ฉํด๋ ๋๋ค.
3. ์์ฑ์ ์ฃผ์ ์ ํ ์ด์
๊ณผ๊ฑฐ) ์์ ์ ์ฃผ์ / ํ๋ ์ฃผ์
์ต๊ทผ) DI ํ๋ ์์ํฌ -> ์์ฑ์ ์ฃผ์ ๊ถ์ฅ
1) ๋ถ๋ณ
- ๋๋ถ๋ถ ์์กด๊ด๊ณ ์ฃผ๋ฆฝ์ ํ ๋ฒ ์ผ์ด๋๋ฉด ์ข ๋ฃ์์ ๊น์ง ์์กด๊ด๊ณ ๋ณ๊ฒฝํ ์ผ ์๋ค
- ์คํ๋ ค ๋ณํ๋ฉด ์๋๋ค
- ์์ ์ ์ฃผ์ ์ set ๋ฉ์๋ public์ผ๋ก ์ด์ด๋ฌ์ผํจ
- ์์ฑ์ ์ฃผ์ ์ ๊ฐ์ฒด ์์ฑ์ ๋ฑ ํ ๋ฒ๋ง ํธ์ถ๋จ
2) ๋๋ฝ
- ํ๋ ์์ํฌ ์์ด ์์ํ ์๋ฐ ์ฝ๋๋ฅผ ๋จ์ํ ์คํธ ํ๋ ๊ฒฝ์ฐ
์์ ์ ์ฃผ์ )
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 ๊ฐ ํ๋ ์์ํฌ ์์์ ๋์ํ ๋๋ ์์กด๊ด๊ณ๊ฐ ์์ผ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง๋ง, ์ง๊ธ์ ํ๋ ์์ํฌ ์์ด ์์ํ ์๋ฐ ์ฝ๋๋ก๋ง ๋จ์ ํ ์คํธ๋ฅผ ์ํํ๊ณ ์๋ค.
@Test
void createOrder() {
OrderServiceImpl orderService = new OrderServiceImpl();
orderService.createOrder(1L, "itemA", 10000);
}
- ์คํ๊ฒฐ๊ณผ NullPointerException -> memberRepo / discountPolicy ๋ชจ๋ ์์กด๊ด๊ณ ๋๋ฝ
BUT
์์ฑ์ ์ฃผ์ ์ฌ์ฉํ๋ฉด,
- ์ฃผ์ ๋ฐ์ดํฐ ๋๋ฝํ์๋ ์ปดํ์ผ ์ค๋ฅ ๋ฐ์
- IDE์์ ์ด๋ค ๊ฐ ํ์๋ก ์ฃผ์ ํด์ผํ๋์ง ์ ์ ์์
final ํค์๋
- ์์ฑ์ ์ฃผ์ ์ฌ์ฉํ๋ฉด ํ๋์ 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;
}
//...
}
ํ์ ํ๋์ธ discountPolicy ์ ๊ฐ์ ์ค์ ํด์ผ ํ๋๋ฐ ๋๋ฝ
-> ์๋ฐ๋ ์ปดํ์ผ ์์ ์ ๋ค์ ์ค๋ฅ๋ฅผ ๋ฐ์์ํจ๋ค.
java: variable discountPolicy might not have been initialized |
๊ธฐ์ตํ์! ์ปดํ์ผ ์ค๋ฅ๋ ์ธ์์์ ๊ฐ์ฅ ๋น ๋ฅด๊ณ , ์ข์ ์ค๋ฅ๋ค!
์ฐธ๊ณ :
์์ ์ ์ฃผ์ ์ ํฌํจํ ๋๋จธ์ง ์ฃผ์ ๋ฐฉ์์ ๋ชจ๋ ์์ฑ์ ์ดํ์ ํธ์ถ๋๋ฏ๋ก, ํ๋์ final ํค์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
์ค์ง ์์ฑ์ ์ฃผ์ ๋ฐฉ์๋ง final ํค์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
์ ๋ฆฌ
- ์์ฑ์ ์ฃผ์
= ํ๋ ์์ํฌ์ ์์กดํ์ง ์๊ณ , ์์ํ ์๋ฐ ์ธ์ด์ ํน์ง์ ์ ์ด๋ฆฌ๋ ๋ฐฉ๋ฒ
- ๊ธฐ๋ณธ์ผ๋ก ์์ฑ์ ์ฃผ์
์ ์ฌ์ฉํ๊ณ , ํ์ ๊ฐ์ด ์๋ ๊ฒฝ์ฐ์๋ ์์ ์ ์ฃผ์
๋ฐฉ์์ ์ต์
์ผ๋ก ๋ถ์ฌ
- ์์ฑ์ ์ฃผ์ ๊ณผ ์์ ์ ์ฃผ์ ์ ๋์์ ์ฌ์ฉํ ์ ์๋ค.
- ํญ์ ์์ฑ์ ์ฃผ์ ์ ์ ํ / ์ต์ ์ด ํ์ํ๋ฉด ์์ ์ ์ฃผ์ ์ ์ ํ
- ํ๋ ์ฃผ์
์ ์ฌ์ฉํ์ง ์๋๊ฒ ์ข์
4. ๋กฌ๋ณต๊ณผ ์ต์ ํธ๋ ๋
๋๋ถ๋ถ ์์ฑ์ ๋ถ๋ณ / ์์ฑ์์ 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;
}
}
> ๋กฌ๋ณต ์ ์ฉ
๋กฌ๋ณต ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ ๊ณตํ๋ @RequiredArgsConstructor ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ฉด final์ด ๋ถ์ ํ๋๋ฅผ ๋ชจ์์ ์์ฑ์๋ฅผ ์๋์ผ๋ก ๋ง๋ค์ด ์ค
(๋ค์ ์ฝ๋์๋ ๋ณด์ด์ง ์์ง๋ง ์ค์ ํธ์ถ ๊ฐ๋ฅ)
@Component
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
}
๋กฌ๋ณต์ด ์๋ฐ์ ์ ๋ ธํ ์ด์ ํ๋ก์ธ์๋ผ๋ ๊ธฐ๋ฅ์ ์ด์ฉํด์ ์ปดํ์ผ ์์ ์ ์์ฑ์ ์ฝ๋๋ฅผ ์๋์ผ๋ก ์์ฑ
์ค์ class ์ด์ด๋ณด๋ฉด ๋ค์ ์ฝ๋ ์ถ๊ฐ๋์๋ ๊ฒ ํ์ธ ๊ฐ๋ฅ
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
์ ๋ฆฌ)
์ต๊ทผ์๋ ์์ฑ์๋ฅผ ๋ฑ 1๊ฐ ๋๊ณ , @Autowired ๋ฅผ ์๋ตํ๋ ๋ฐฉ๋ฒ์ ์ฃผ๋ก ์ฌ์ฉ
์ฌ๊ธฐ์ Lombok ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ @RequiredArgsConstructor ํจ๊ป ์ฌ์ฉ (์์ฑ์ ์๋ตํด์ฃผ๋ ๋กฌ๋ณต)
๋กฌ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ์ฉ ๋ฐฉ๋ฒ
- build.gradle์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฐ ํ๊ฒฝ ์ถ๊ฐ (or spring.io์์ dependecies๋ก ์ถ๊ฐ ๊ฐ๋ฅ)
plugins {
id 'org.springframework.boot' version '2.3.2.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.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') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
} }
test {
useJUnitPlatform()
}
1. Preferences(์๋์ฐ File Settings) plugin lombok ๊ฒ์ ์ค์น ์คํ (์ฌ์์)
2. Preferences Annotation Processors ๊ฒ์ -> enable annotation processing ์ฒดํฌ (์ฌ์์)
3. ์์์ ํ ์คํธ ํด๋์ค๋ฅผ ๋ง๋ค๊ณ @Getter, @Setter ํ์ธ -> ์๋์ผ๋ก ์์ฑํด์ค
@Getter
@Setter
public class Lombokk{
private String name;
private int age;
}
+
@ToString : toString ์๋ ์์ฑ
@RequiredArgsContructor : ์์ฑ์ ์๋ ์์ฑ
5. ์กฐํ ๋น์ด 2๊ฐ ์ด์ - ๋ฌธ์
@Autowired - ํ์ ์ผ๋ก ์กฐํ = ๋ง์น ๋ค์ ์ฝ๋์ ์ ์ฌํ๊ฒ ๋์ํ๋ค. (์ค์ ๋ก๋ ๋ ๋ง์ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.)
ac.getBean(DiscountPolicy.class)
ํ์ ์ผ๋ก ์กฐํํ๋ฉด ์ ํ๋ ๋น์ด 2๊ฐ ์ด์์ผ ๋ ๋ฌธ์ ๋ฐ์
@Component
public class FixDiscountPolicy implements DiscountPolicy {}
@Component
public class RateDiscountPolicy implements DiscountPolicy {}
@Autowired
private DiscountPolicy discountPolicy
-> ์ค๋ฅ ๋ฐ์ ( NoUniqueBeanDefinitionException )
ํด๊ฒฐ)
ํ์ํ์ ์ง์ ? -> DIP ์๋ฐ + ์ ์ฐ์ฑ ๋จ์ด์ง
6. ๋น ์ฌ๋ฌ๊ฐ ์ ํ ํด๊ฒฐ๋ฐฉ์
1)@Autowired ํ๋๋ช ๋งค์นญ
2) @Quilifier - @Quilifier๋ผ๋ฆฌ ๋งค์นญ -> ๋น ์ด๋ฆ ๋งค์นญ
3) @Primary ์ฌ์ฉ
<1> @Autowired ํ๋๋ช ๋งค์นญ
- Autowired๋ ํ์ ๋งค์นญ์ ์๋ํ๊ณ ์ด๋ ์ฌ๋ฌ ๋น์ด ์์ผ๋ฉด ํ๋ ์ด๋ฆ (ํ๋ผ๋ฏธํฐ ์ด๋ฆ)์ผ๋ก ๋น์ด๋ฆ์ ์ถ๊ฐ ๋งค์นญ
> ๊ธฐ์กด ์ฝ๋
@Autowired
private DiscountPolicy discountPolicy
> ํ๋ ๋ช ์ ๋น ์ด๋ฆ์ผ๋ก ๋ณ๊ฒฝ
@Autowired
private DiscountPolicy rateDiscountPolicy
- ํ๋ ๋ช ์ด rateDiscountPolicy์ด๊ธฐ ๋๋ฌธ์ ์ ์ ์ฃผ์
- ํ๋ ๋ช ๋งค์นญ์ ๋จผ์ ํ์ ๋งค์นญ์ ์๋ํ๊ณ , ๊ทธ ๊ฒฐ๊ณผ์ ์ฌ๋ฌ ๋น์ด ์์ ๋ ์ถ๊ฐ๋ก ๋์ํ๋ ๊ธฐ๋ฅ
@Autowired ๋งค์นญ ์ ๋ฆฌ
1) ํ์ ๋งค์นญ
2) ํ์ ๋งค์นญ์ ๊ฒฐ๊ณผ๊ฐ ๋ ๊ฐ ์ด์์ผ ๋ ํ๋๋ช /ํ๋ผ๋ฏธํฐ๋ช ์ผ๋ก ๋น ์ด๋ฆ ๋งค์นญ
<2> @Qualifier ์ฌ์ฉ
- ์ถ๊ฐ ๊ตฌ๋ถ์ ๋ถ์ฌ์ฃผ๋ ๋ฐฉ์ (๋น์ด๋ฆ ๋ณ๊ฒฝ ์๋)
@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy {}
@Component
@Qualifier("fixDiscountPolicy")
public class FixDiscountPolicy implements DiscountPolicy {}
ex) ์์ฑ์ ์๋ ์ฃผ์
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, @Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
ex) ์์ ์ ์๋ ์ฃผ์
@Autowired
public DiscountPolicy setDiscountPolicy(@Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
๋น๋ฑ๋ก์์๋ ๊ฐ๋ฅ
@Bean
@Qualifier("mainDiscountPolicy")
public DiscountPolicy discountPolicy() {
return new ...
}
์ ๋ฆฌ)
1. @Qualifier๋ผ๋ฆฌ ๋งค์นญ
2. ๋น ์ด๋ฆ ๋งค์นญ
3. NoSuchBeanDefinitionException ์์ธ ๋ฐ์
<3> @Primary ์ฌ์ฉ
- ์ฐ์ ์์๋ฅผ ์ ํ๋ ๋ฐฉ๋ฒ (์์ฃผ ์ฌ์ฉ)
ex) rateDiscountPolicy๊ฐ ์ฐ์ ๊ถ ๊ฐ์ง๋๋ก
@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy {}
@Component
public class FixDiscountPolicy implements DiscountPolicy {}
์ฌ์ฉ์ฝ๋
//์์ฑ์
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
//์์ ์
@Autowired
public DiscountPolicy setDiscountPolicy(DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
@Primary ์์ฃผ ์ฐ๋ ์ด์
-> ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ปค๋ฅ์ ๊ด๋ จ
๋ฉ์ธ db, ๋ณด์กฐ db => ๋ฉ์ธ / ๋ณด์กฐ ๊ฐ์ ธ์ฌ๋ qualifier ํด์ฃผ๋๊ฒ ๊ท์ฐฎ์ผ๋ ๋ฉ์ธ db ์ปค๋ฅ์ ๊ฑธ์ด์ค๋ primary
๋ณด์กฐ db์ ๊ฒฝ์ฐ qualifier๋ ์ง์ ์ด๋ฆ ์ง์ ํ๋ ์์ผ๋ก ์ฌ์ฉ
์๋ ๋๊ฐ์ ์๊ธฐ ๊ธธ๊ฒ
@Primary, @Qualifier ํ์ฉ ์ฝ๋์์ ์์ฃผ ์ฌ์ฉํ๋ ๋ฉ์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ปค๋ฅ์ ์ ํ๋ํ๋ ์คํ๋ง ๋น์ด ์๊ณ , ์ฝ๋์์ ํน๋ณํ ๊ธฐ๋ฅ์ผ๋ก ๊ฐ๋ ์ฌ์ฉํ๋ ์๋ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ปค๋ฅ์ ์ ํ๋ํ๋ ์คํ๋ง ๋น์ด ์๋ค๊ณ ์๊ฐํด๋ณด์. ๋ฉ์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ปค๋ฅ์ ์ ํ๋ํ๋ ์คํ๋ง ๋น์ @Primary ๋ฅผ ์ ์ฉํด์ ์กฐํํ๋ ๊ณณ์์ @Qualifier ์ง์ ์์ด ํธ๋ฆฌํ๊ฒ ์กฐํํ๊ณ , ์๋ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ปค๋ฅ์ ๋น์ ํ๋ํ ๋๋ @Qualifier ๋ฅผ ์ง์ ํด์ ๋ช ์์ ์ผ๋ก ํ๋ ํ๋ ๋ฐฉ์์ผ๋ก ์ฌ์ฉํ๋ฉด ์ฝ๋๋ฅผ ๊น๋ํ๊ฒ ์ ์งํ ์ ์๋ค. ๋ฌผ๋ก ์ด๋ ๋ฉ์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์คํ๋ง ๋น์ ๋ฑ๋กํ ๋ @Qualifier ๋ฅผ ์ง์ ํด์ฃผ๋ ๊ฒ์ ์๊ด์๋ค. ์ฐ์ ์์
@Primary ๋ ๊ธฐ๋ณธ๊ฐ ์ฒ๋ผ ๋์ํ๋ ๊ฒ์ด๊ณ , @Qualifier ๋ ๋งค์ฐ ์์ธํ๊ฒ ๋์ํ๋ค. ์ด๋ฐ ๊ฒฝ์ฐ ์ด๋ค ๊ฒ์ด ์ฐ์ ๊ถ์ ๊ฐ์ ธ๊ฐ๊น? ์คํ๋ง์ ์๋๋ณด๋ค๋ ์๋์ด, ๋์ ๋ฒ์์ ์ ํ๊ถ ๋ณด๋ค๋ ์ข์ ๋ฒ์์ ์ ํ๊ถ์ด ์ฐ์ ์์๊ฐ ๋๋ค. ๋ฐ๋ผ์ ์ฌ๊ธฐ์๋ @Qualifier ๊ฐ ์ฐ์ ๊ถ์ด ๋๋ค. |
* qualifier ๋จ์ : ๋ชจ๋ ์ฝ๋์ ๋ถ์ฌ์ค์ผํจ
7. Annotation ์ง์ ๋ง๋ค๊ธฐ
@Qualifier("mainDiscountPolicy") ์ด๋ ๊ฒ ๋ฌธ์๋ฅผ ์ ์ผ๋ฉด ์ปดํ์ผ์ ํ์ ์ฒดํฌ๊ฐ ์๋๋ค.
-> Annotation ๋ง๋ค์ด์ ํด๊ฒฐ
@interface
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER,
ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Qualifier("mainDiscountPolicy")
public @interface MainDiscountPolicy {
}
@Component
@MainDiscountPolicy
public class RateDiscountPolicy implements DiscountPolicy {}
//์์ฑ์ ์๋ ์ฃผ์
@Autowired
public OrderServiceImpl(MemberRepository memberRepository,
@MainDiscountPolicy DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
//์์ ์ ์๋ ์ฃผ์
@Autowired
public DiscountPolicy setDiscountPolicy(@MainDiscountPolicy DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
์ ๋
ธํ
์ด์
์๋ ์์์ด๋ผ๋ ๊ฐ๋
์ด ์๋ค. ์ด๋ ๊ฒ ์ฌ๋ฌ ์ ๋
ธํ
์ด์
์ ๋ชจ์์ ์ฌ์ฉํ๋ ๊ธฐ๋ฅ์ ์คํ๋ง์ด ์ง์ํด์ฃผ๋ ๊ธฐ๋ฅ์ด๋ค.
@Qulifier ๋ฟ๋ง ์๋๋ผ ๋ค๋ฅธ ์ ๋ ธํ ์ด์ ๋ค๋ ํจ๊ป ์กฐํฉํด์ ์ฌ์ฉํ ์ ์๋ค. ๋จ์ ์ผ๋ก @Autowired๋ ์ฌ์ ์ ํ ์ ์๋ค. ๋ฌผ๋ก ์คํ๋ง์ด ์ ๊ณตํ๋ ๊ธฐ๋ฅ์ ๋๋ ทํ ๋ชฉ์ ์์ด ๋ฌด๋ถ๋ณํ๊ฒ ์ฌ์ ์ ํ๋ ๊ฒ์ ์ ์ง๋ณด์์ ๋ ํผ๋๋ง ๊ฐ์คํ ์ ์๋ค. |
8. ์กฐํํ ๋น์ด ๋ชจ๋ ํ์ํ ๋, List, Map
public class AllBeanTest {
@Test
void findAllBean() {
ApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class, DiscountService.class);
DiscountService discountService = ac.getBean(DiscountService.class);
Member member = new Member(1L, "userA", Grade.VIP);
int discountPrice = discountService.discount(member, 10000, "fixDiscountPolicy");
assertThat(discountService).isInstanceOf(DiscountService.class);
assertThat(discountPrice).isEqualTo(1000);
}
static class DiscountService {
private final Map<String, DiscountPolicy> policyMap;
private final List<DiscountPolicy> policies;
@Autowired
public DiscountService(Map<String, DiscountPolicy> policyMap, List<DiscountPolicy> policies) {
this.policyMap = policyMap;
this.policies = policies;
System.out.println("policyMap = " + policyMap);
System.out.println("policies = " + policies);
}
public int discount(Member member, int price, String discountCode) {
DiscountPolicy discountPolicy = policyMap.get(discountCode);
System.out.println("discountCode = " + discountCode);
System.out.println("discountPolicy = " + discountPolicy);
return discountPolicy.discount(member, price);
}
}
}
[๋ก์ง]
DiscountService๋ Map์ผ๋ก ๋ชจ๋ DiscountPolicy ๋ฅผ ์ฃผ์
๋ฐ๋๋ค.
์ด๋ fixDiscountPolicy , rateDiscountPolicy ๊ฐ ์ฃผ์ ๋๋ค. discount () ๋ฉ์๋๋ discountCode๋ก "fixDiscountPolicy"๊ฐ ๋์ด์ค๋ฉด map์์ fixDiscountPolicy ์คํ๋ง ๋น์ ์ฐพ์์ ์คํํ๋ค. ๋ฌผ๋ก “rateDiscountPolicy”๊ฐ ๋์ด์ค๋ฉด rateDiscountPolicy ์คํ๋ง ๋น์ ์ฐพ์์ ์คํํ๋ค. |
[์ฃผ์ ๋ถ์]
Map<String, DiscountPolicy> : map์ ํค์ ์คํ๋ง ๋น์ ์ด๋ฆ์ ๋ฃ์ด์ฃผ๊ณ , ๊ทธ ๊ฐ์ผ๋ก DiscountPolicy ํ์
์ผ๋ก ์กฐํํ ๋ชจ๋ ์คํ๋ง ๋น์ ๋ด์์ค๋ค.
List<DiscountPolicy> : DiscountPolicy ํ์ ์ผ๋ก ์กฐํํ ๋ชจ๋ ์คํ๋ง ๋น์ ๋ด์์ค๋ค. ๋ง์ฝ ํด๋นํ๋ ํ์ ์ ์คํ๋ง ๋น์ด ์์ผ๋ฉด, ๋น ์ปฌ๋ ์ ์ด๋ Map์ ์ฃผ์ ํ๋ค. |
[์ฐธ๊ณ ]
์คํ๋ง ์ปจํ
์ด๋๋ฅผ ์์ฑํ๋ฉด์ ์คํ๋ง ๋น ๋ฑ๋กํ๊ธฐ
์คํ๋ง ์ปจํ ์ด๋๋ ์์ฑ์์ ํด๋์ค ์ ๋ณด๋ฅผ ๋ฐ๋๋ค. ์ฌ๊ธฐ์ ํด๋์ค ์ ๋ณด๋ฅผ ๋๊ธฐ๋ฉด ํด๋น ํด๋์ค๊ฐ ์คํ๋ง ๋น์ผ๋ก ์๋ ๋ฑ๋ก๋๋ค. new AnnotationConfigApplicationContext(AutoAppConfig.class,DiscountService.class); ใด ์ด ์ฝ๋๋ 2๊ฐ์ง๋ก ๋๋์ด ์ดํดํ ์ ์๋ค. 1) new AnnotationConfigApplicationContext() ๋ฅผ ํตํด ์คํ๋ง ์ปจํ
์ด๋๋ฅผ ์์ฑํ๋ค.
2) AutoAppConfig.class , DiscountService.class ๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๋๊ธฐ๋ฉด์ ํด๋น ํด๋์ค๋ฅผ ์๋์ผ๋ก ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ๋ค. ์ ๋ฆฌํ๋ฉด ์คํ๋ง ์ปจํ ์ด๋๋ฅผ ์์ฑํ๋ฉด์, ํด๋น ์ปจํ ์ด๋์ ๋์์ AutoAppConfig , DiscountService ๋ฅผ ์คํ๋ง ๋น์ผ๋ก ์๋ ๋ฑ๋กํ๋ค. |
9. ์๋, ์๋์ ์ฌ๋ฐ๋ฅธ ์ค๋ฌด ์ด์ ๊ธฐ์ค
์ ํ๋ฆฌ์ผ์ด์
์ ํฌ๊ฒ ์
๋ฌด ๋ก์ง๊ณผ ๊ธฐ์ ์ง์ ๋ก์ง์ผ๋ก ๋๋ ์ ์๋ค.
์ ๋ฌด ๋ก์ง ๋น: ์น์ ์ง์ํ๋ ์ปจํธ๋กค๋ฌ, ํต์ฌ ๋น์ฆ๋์ค ๋ก์ง์ด ์๋ ์๋น์ค, ๋ฐ์ดํฐ ๊ณ์ธต์ ๋ก์ง์ ์ฒ๋ฆฌํ๋ ๋ฆฌํฌ์งํ ๋ฆฌ๋ฑ์ด ๋ชจ๋ ์ ๋ฌด ๋ก์ง์ด๋ค. ๋ณดํต ๋น์ฆ๋์ค ์๊ตฌ์ฌํญ์ ๊ฐ๋ฐํ ๋ ์ถ๊ฐ๋๊ฑฐ๋ ๋ณ๊ฒฝ๋๋ค. (DAO ๊ฐ์) ๊ธฐ์ ์ง์ ๋น: ๊ธฐ์ ์ ์ธ ๋ฌธ์ ๋ ๊ณตํต ๊ด์ฌ์ฌ(AOP)๋ฅผ ์ฒ๋ฆฌํ ๋ ์ฃผ๋ก ์ฌ์ฉ๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ด๋, ๊ณตํต ๋ก๊ทธ ์ฒ๋ฆฌ ์ฒ๋ผ ์ ๋ฌด ๋ก์ง์ ์ง์ํ๊ธฐ ์ํ ํ๋ถ ๊ธฐ์ ์ด๋ ๊ณตํต ๊ธฐ์ ๋ค์ด๋ค. ์ ๋ฌด ๋ก์ง์ ์ซ์๋ ๋งค์ฐ ๋ง๊ณ , ํ๋ฒ ๊ฐ๋ฐํด์ผ ํ๋ฉด ์ปจํธ๋กค๋ฌ, ์๋น์ค, ๋ฆฌํฌ์งํ ๋ฆฌ ์ฒ๋ผ ์ด๋์ ๋ ์ ์ฌํ ํจํด์ด ์๋ค. ์ด๋ฐ ๊ฒฝ์ฐ ์๋ ๊ธฐ๋ฅ์ ์ ๊ทน ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค. ๋ณดํต ๋ฌธ์ ๊ฐ ๋ฐ์ํด๋ ์ด๋ค ๊ณณ์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋์ง ๋ช ํํ๊ฒ ํ์ ํ๊ธฐ ์ฝ๋ค. ๊ธฐ์ ์ง์ ๋ก์ง์ ์ ๋ฌด ๋ก์ง๊ณผ ๋น๊ตํด์ ๊ทธ ์๊ฐ ๋งค์ฐ ์ ๊ณ , ๋ณดํต ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐ์ ๊ฑธ์ณ์ ๊ด๋ฒ์ํ๊ฒ ์ํฅ์ ๋ฏธ์น๋ค. ๊ทธ๋ฆฌ๊ณ ์ ๋ฌด ๋ก์ง์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ ๋ ์ด๋๊ฐ ๋ฌธ์ ์ธ์ง ๋ช ํํ๊ฒ ์ ๋๋ฌ๋์ง๋ง, ๊ธฐ์ ์ง์ ๋ก์ง์ ์ ์ฉ์ด ์ ๋๊ณ ์๋์ง ์๋์ง ์กฐ์ฐจ ํ์ ํ๊ธฐ ์ด๋ ค์ด ๊ฒฝ์ฐ๊ฐ ๋ง๋ค. ๊ทธ๋์ ์ด๋ฐ ๊ธฐ์ ์ง์ ๋ก์ง๋ค์ ๊ฐ๊ธ์ ์๋ ๋น ๋ฑ๋ก์ ์ฌ์ฉํด์ ๋ช ํํ๊ฒ ๋๋ฌ๋ด๋ ๊ฒ์ด ์ข๋ค. |
์ ํ๋ฆฌ์ผ์ด์ ์ ๊ด๋ฒ์ํ๊ฒ ์ํฅ์ ๋ฏธ์น๋ ๊ธฐ์ ์ง์ ๊ฐ์ฒด๋ ์๋ ๋น์ผ๋ก ๋ฑ๋กํด์ ๋ฑ! ์ค์ ์ ๋ณด์ ๋ฐ๋ก ๋ํ๋๊ฒ ํ๋ ๊ฒ์ด ์ ์ง๋ณด์ ํ๊ธฐ ์ข๋ค.
๋น์ฆ๋์ค ๋ก์ง ์ค์์ ๋คํ์ฑ์ ์ ๊ทน ํ์ฉํ ๋
์์กด๊ด๊ณ ์๋ ์ฃผ์
- ์กฐํํ ๋น์ด ๋ชจ๋ ํ์ํ ๋, List, Map์ ๋ค์ ๋ณด์. DiscountService ๊ฐ ์์กด๊ด๊ณ ์๋ ์ฃผ์ ์ผ๋ก Map<String, DiscountPolicy> ์ ์ฃผ์ ์ ๋ฐ๋ ์ํฉ์ ์๊ฐํด๋ณด์. ์ฌ๊ธฐ์ ์ด๋ค ๋น๋ค์ด ์ฃผ์ ๋ ์ง, ๊ฐ ๋น๋ค์ ์ด๋ฆ์ ๋ฌด์์ผ์ง ์ฝ๋๋ง ๋ณด๊ณ ํ๋ฒ์ ์ฝ๊ฒ ํ์ ํ ์ ์์๊น? ์๋ ๋ฑ๋ก์ ์ฌ์ฉํ๊ณ ์๊ธฐ ๋๋ฌธ์ ํ์ ํ๋ ค๋ฉด ์ฌ๋ฌ ์ฝ๋๋ฅผ ์ฐพ์๋ด์ผ ํ๋ค. ์ด๋ฐ ๊ฒฝ์ฐ ์๋ ๋น์ผ๋ก ๋ฑ๋กํ๊ฑฐ๋ ๋๋ ์๋์ผ๋กํ๋ฉด ํน์ ํจํค์ง์ ๊ฐ์ด ๋ฌถ์ด๋๋๊ฒ ์ข๋ค! ํต์ฌ์ ๋ฑ ๋ณด๊ณ ์ดํด๊ฐ ๋์ด์ผ ํ๋ค! |
์ด ๋ถ๋ถ์ ๋ณ๋์ ์ค์ ์ ๋ณด๋ก ๋ง๋ค๊ณ ์๋์ผ๋ก ๋ฑ๋กํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
@Configuration
public class DiscountPolicyConfig {
@Bean
public DiscountPolicy rateDiscountPolicy() {
return new RateDiscountPolicy();
}
@Bean
public DiscountPolicy fixDiscountPolicy() {
return new FixDiscountPolicy();
}
}
์ด ์ค์ ์ ๋ณด๋ง ๋ด๋ ํ๋์ ๋น์ ์ด๋ฆ์ ๋ฌผ๋ก ์ด๊ณ , ์ด๋ค ๋น๋ค์ด ์ฃผ์ ๋ ์ง ํ์ ํ ์ ์๋ค.
๊ทธ๋๋ ๋น ์๋ ๋ฑ๋ก์ ์ฌ์ฉํ๊ณ ์ถ์ผ๋ฉด ํ์ ํ๊ธฐ ์ข๊ฒ DiscountPolicy ์ ๊ตฌํ ๋น๋ค๋ง ๋ฐ๋ก ๋ชจ์์ ํน์ ํจํค์ง์ ๋ชจ์๋์.
์ฐธ๊ณ ๋ก ์คํ๋ง๊ณผ ์คํ๋ง ๋ถํธ๊ฐ ์๋์ผ๋ก ๋ฑ๋กํ๋ ์ ๋ง์ ๋น๋ค์ ์์ธ๋ค. ์ด๋ฐ ๋ถ๋ถ๋ค์ ์คํ๋ง ์์ฒด๋ฅผ ์ ์ดํดํ๊ณ ์คํ๋ง์ ์๋๋๋ก ์ ์ฌ์ฉํ๋๊ฒ ์ค์ํ๋ค. ์คํ๋ง ๋ถํธ์ ๊ฒฝ์ฐ DataSource ๊ฐ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ ์ฌ์ฉํ๋ ๊ธฐ์ ์ง์ ๋ก์ง๊น์ง ๋ด๋ถ์์ ์๋์ผ๋ก ๋ฑ๋กํ๋๋ฐ, ์ด๋ฐ ๋ถ๋ถ์ ๋ฉ๋ด์ผ์ ์ ์ฐธ๊ณ ํด์ ์คํ๋ง ๋ถํธ๊ฐ ์๋ํ ๋๋ก ํธ๋ฆฌํ๊ฒ ์ฌ์ฉํ๋ฉด ๋๋ค. ๋ฐ๋ฉด์ ์คํ๋ง ๋ถํธ๊ฐ ์๋๋ผ ๋ด๊ฐ ์ง์ ๊ธฐ์ ์ง์ ๊ฐ์ฒด๋ฅผ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ๋ค๋ฉด ์๋์ผ๋ก ๋ฑ๋กํด์ ๋ช ํํ๊ฒ ๋๋ฌ๋ด๋ ๊ฒ์ด ์ข๋ค. |
์ ๋ฆฌ
ํธ๋ฆฌํ ์๋ ๊ธฐ๋ฅ์ ๊ธฐ๋ณธ์ผ๋ก ์ฌ์ฉํ์ ์ง์ ๋ฑ๋กํ๋ ๊ธฐ์ ์ง์ ๊ฐ์ฒด๋ ์๋ ๋ฑ๋ก ๋คํ์ฑ์ ์ ๊ทน ํ์ฉํ๋ ๋น์ฆ๋์ค ๋ก์ง์ ์๋ ๋ฑ๋ก์ ๊ณ ๋ฏผํด๋ณด์ |
'๐จโ๐ป Web Development > Spring - ๊ธฐ๋ณธ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring] 9.๋น ์ค์ฝํ (0) | 2023.03.01 |
---|---|
[Spring] 8.๋น ์๋ช ์ฃผ๊ธฐ ์ฝ๋ฐฑ (0) | 2023.02.28 |
[Spring] 6.์ปดํฌ๋ํธ ์ค์บ (0) | 2023.02.24 |
[Spring] 5.์ฑ๊ธํค ์ปจํ ์ด๋ (0) | 2023.02.22 |
[Spring] 4.์คํ๋ง ์ปจํ ์ด๋์ ์คํ๋ง ๋น (0) | 2023.02.20 |
์ต๊ทผ๋๊ธ