Springμ λν΄ μ²μ 곡λΆνλ μ¬λμ΄ μ 리λ₯Ό λͺ©μ μΌλ‘ μμ±ν κΈμ λλ€. μ€κ°λ λ± μλͺ»λ λΆλΆμ΄ μμ κ²½μ° λκΈλ‘ κ°κ°μμ΄ μ§μ ν΄μ£ΌμΈμ! νμΈνλ λλ‘ μ νν μ 보λ₯Ό κΈ°λ°ν΄ λΉ λ₯΄κ² μμ ν μ μλλ‘ νκ² μ΅λλ€.
κ°μ
μ΄λ² Spring Boot μ€ν°λλ λ°°λ¬μ λ―Όμ‘±μ κΉμνλκ»μ μΈνλ°μ μ¬λ €μ£Όμλ μλ° μ€νλ§ μμ μ 볡 μ리μ¦λ₯Ό κΈ°λ°μΌλ‘ μ§ννλ€. κ·Έ μ리μ¦μ κ°μ₯ 첫 κ°μμΈ μ€νλ§ μ λ¬Έ - μ½λλ‘ λ°°μ°λ μ€νλ§ λΆνΈ, μΉ MVC, DB μ κ·Ό κΈ°μ μ λλ΄κ³ , λ€μ κ°μμΈ μ€νλ§ ν΅μ¬ μ리 - κΈ°λ³ΈνΈμ μ 리ν΄λ³΄λ € νλ€.
μ΄λ² ν¬μ€νΈμμλ μ±κΈν€ 컨ν μ΄λμ λν κ²μ κ°λ¨ν μ 리ν΄λ³΄λλ‘ νκ² λ€.
μ±κΈν€μ μ¬μ©νλ μ΄μ
μ±κΈν€μ μ¬μ©νλ μ΄μ λ₯Ό λ μ¬λ € 보기 μν΄ μμΌλ‘ μ±κΈν€μ μ¬μ©νμ§ μμ λ λ°μνλ λ¬Έμ μ μ λν΄μ μμ보λλ‘ νμ. κ°μ²΄μ§ν₯ νλ‘κ·Έλλ°μ λν΄μ, νΉμ μλ°μ λν΄μ λνκ΅ κ°μμμ μ²μ μ ν λ§μ μ¬λλ€μ μ±κΈν€ ν¨ν΄μ μν°ν¨ν΄μΌλ‘ μκ³ μμ κ²μ΄λ€.
μ€μ λ‘ κ·Έλ λ€. μ±κΈν€ ν¨ν΄μ μλ§μ λ¨μ μ΄ μλ€. μλ₯Ό λ€μ΄,
- μλ°μμλ μ±κΈν€ ν¨ν΄μ ꡬννκΈ° μν΄ λΆκ°μ μΌλ‘ μ½λλ₯Ό λ΄λΆμ λ μμ±ν΄μ£Όμ΄μΌ νλ€.
- μμ±μκ° private νκΈ° λλ¬Έμ μμ ν΄λμ€λ₯Ό λ§λ€κΈ° μ΄λ ΅λ€. μ¦, μμμ μ΄μ©ν μΆμνμ λΆλ¦¬νλ€.
- μ¬μ€μ ν΄λμ€ λ΄λΆμ μνκ° staticν μνκ° λκΈ° λλ¬Έμ μΊ‘μνμ κ΄μ μμ κ°μ²΄ μ§ν₯μ μ² νκ³Ό κ±°λ¦¬κ° μλ€.
- μ±κΈν€ κ°μ²΄ λ΄λΆμμ μΈμ€ν΄μ€λ₯Ό κΊΌλ΄κΈ° μν΄μ
getInstance()
λ₯Ό νΈμΆν΄μΌ νλλ°, μ΄ κ²μ μ΄λ¦μ΄getInstance()
κ° λ μ§ μλλ©΄get()
μ΄ λ μ§, κ·Έλ¦¬κ³ νλΌλ―Έν°λ‘λ λ μ λ¬ν μ§ μ무λ μμΈ‘ν μ μλ€. μ¦ μ¬μ©νλ μͺ½μμ ꡬν체μ μμ‘΄νκ² λμ΄ DIPλ₯Ό μλ°νκ² λλ€.
λ±μ λ¨μ μ΄ μλ€.
κ·ΈλΌμλ λΆκ΅¬νκ³ μ±κΈν€μ μ¬μ©ν μ λ°μ μλ μ΄μ λ μΉ μ΄ν리μΌμ΄μ
μΌλ‘ λμμ λ§μ μμ²μ΄ λ€μ΄μ€κΈ° λλ¬Έμ΄λ€. λ μλ°νκ² νμ΄λ³΄μλ©΄, λμμ λ€μ΄μ€λ λ§μ μμ²μ λν΄μ κ° μμ²λ§λ€ new
ν€μλλ₯Ό ν΅ν΄ κ°μ²΄λ₯Ό μμ±ν κ²½μ° λ©λͺ¨λ¦¬ λΉμ©κ³Ό GC λΉμ©μ΄ μΉμκ² λκΈ° λλ¬Έμ΄λ€. μλ₯Ό λ€μ΄, μμ² 1000κ°λ©΄ κ°μ²΄ 1000κ°, μμ² 10000κ°λ©΄ κ°μ²΄ 10000κ°λ₯Ό μμ±ν΄μΌ νλ€.
μ±κΈν€ ν¨ν΄μ μ¬μ©νλ©΄ μ΄λ¬ν κ°μ²΄ μμ± λ° λ©λͺ¨λ¦¬ κ΄λ¦¬μ λ¬Έμ μμ λΉκ΅μ μμ λ‘μμ§ μ μλ€.
κ·Όλ° λ¨μ μ΄ μ°μ°νλ°?
νμ€ν κ°μ²΄μ§ν₯μ μ κ΄μ μμ μ±κΈν€ ν¨ν΄μ λ¨μ μ μ© μ μΎνκ² λκ»΄μ§μ§ μλλ€. μ€νλ§μ κ°λ°μλ€μκ² λΆμΎνκ² λ€κ°μ¬ μ μλ μ΄ λ¨μ λ€μ νλ μμν¬ λ¨μμ ν΄κ²°ν΄μ€λ€.
μ€νλ§ μ±κΈν€ 컨ν μ΄λ
μ€νλ§ μ»¨ν μ΄λλ μ±κΈν€ ν¨ν΄μ λ¬Έμ λ₯Ό ν΄κ²°νλ©΄μ κ°μ²΄ μΈμ€ν΄μ€λ μ±κΈν€μΌλ‘ κ΄λ¦¬ν΄μ€λ€. π€ μ΄λ»κ²?
- μ€νλ§ μ»¨ν
μ΄λλ μ±κΈν€μ μ½λλ₯Ό ν΅ν΄μ μ μ©νμ§ μλλΌλ μμμ κ°μ²΄ μΈμ€ν΄μ€λ₯Ό μ±κΈν€μΌλ‘ κ΄λ¦¬νλ€.
- μ μ΄μ 컨ν μ΄λ μμ± κ³Όμ μμ 컨ν μ΄λλ κ°μ²΄λ₯Ό νλλ§ μμ±ν΄μ κ΄λ¦¬νλ€.
- μ€νλ§ μ»¨ν μ΄λλ μ΄λ κ² μμ±λ μ±κΈν€ κ°μ²΄λ€μ κ΄λ¦¬νλ μ±κΈν€ 컨ν μ΄λ μν μ νλ€. μ΄λ κ² μ±κΈν€ κ°μ²΄λ₯Ό μμ±νκ³ κ΄λ¦¬νλ κ²μ μ±κΈν€ λ μ§μ€νΈλ¦¬λΌκ³ νκΈ°λ νλ€.
- μ€νλ§ μ»¨ν
μ΄λμ κΈ°λ₯μ νμ
μ΄, κ°λ°μμ μ
μ₯μμλ μ±κΈν€ ν¨ν΄μ λ¨μ μ ν΄κ²°νλ©΄μ κ·Έλλ‘ μ±κΈν€ ν¨ν΄μ μ₯μ μ λ릴 μ μλ€.
- μ±κΈν€ ν¨ν΄μ ꡬννκΈ° μν μΆκ°μ μΈ μ½λλ₯Ό μμ±νμ§ μμλ λλ€.
- DIP, OCP, ν
μ€νΈ,
private
μμ±μλ‘λΆν° μμ λ‘κ² μ±κΈν€ ν¨ν΄μ μ¬μ©ν μ μκ² λλ€.
λ¬Όλ‘ μ±κΈν€λ§ ν΄μ£Όλ건 μλ
μ€νλ§μ λ¬Όλ‘ μ±κΈν€ μ΄μΈμλ μμ²λ§λ€ μλ‘μ΄ κ°μ²΄λ₯Ό μμ±ν΄μ μ¬μ©νλ λ°©λ²λ μ§μνλ€. μ΄λ λΉ μ€μ½νμ λν΄μ νμ΅ν λ λ€μ λ€λ€λ³΄λλ‘ νκ² λ€.
μ±κΈν€ μ¬μ© μ μ£Όμν΄μΌ ν μ
μ€νλ§μ μ¬μ©νλ κ²κ³Όλ 무κ΄νκ², μ±κΈν€μ μ¬μ©νλ κ² μ체μ μμ΄μ μ£Όμν΄μΌ ν μ μ μνμ λν κ΄λ¦¬μ΄λ€. κ°μ²΄ μΈμ€ν΄μ€ νλλ₯Ό 곡μ ν΄μ μ¬μ©νλ μ±κΈν€μ νΉμ± μ, μ±κΈν€ κ°μ²΄λ μ λ Stateful νκ² μ€κ³ν΄μλ μλλ€. Instance Field, Static Field λͺ¨λ μμ΄μΌ νλ€λ μλ―Έμ΄λ€. (μ¬μ€μ Instance Fieldλ μ±κΈν€μμλ JVM λ°νμμ μ¬λΌκ° λ λ°λ‘ λ‘λ©λμ§ μμ λΏμ΄μ§, νλ² λ‘λ©λ μ΄νμλ Static Fieldμ μ°¨μ΄λ₯Ό κ°μ§μ§ μλλ€.)
μνκ° μ μ§λλ μ½λμ λ¬Έμ μν©
Stateful νκ² μ€κ³νλ©΄ νΉν μ¬λ¬κ°μ μ°λ λκ° κ°μ μΈμ€ν΄μ€μ μ κ·Όνμ λ, κ·Έλ¦¬κ³ ν΄λΉ Stateλ₯Ό λ³κ²½νλ μ½λμ ν¨κ» μ κ·Όν λ μ¬κ°ν λ¬Έμ λ₯Ό μΌκΈ°ν μ μλ€. λ€μ μμ μ ν¨κ» μκ°ν΄λ³΄μ.
public class StatefulService {
private int price; // μνλ₯Ό μ μ§νλ νλ
public void order(String name, int price) {
System.out.println("name = " + name + " price = " + price);
this.price = price; // μ¬κΈ°κ° λ¬Έμ !
}
public int getPrice() {
return price;
}
}
μμ κ°μ μ±κΈν€ μλΉμ€κ° μλ€κ³ μκ°νμ. μ΄μ μ΄ μλΉμ€λ₯Ό μ¬μ©νλ λ€μμ μ½λ μνμ€κ° μλ€κ³ κ°μ νμ.
public int sampleSequence(String nameFromRequest, int priceFromDB) {
this.statefulService.order(nameFromRequest, priceFromDB);
return this.statefulService.getPrice(); // μ§μ§ μ¬κ³ λ°μ
}
μνμ€λ₯Ό 보면 order
μ¦ μ£Όλ¬Έμ νκ³ , μ£Όλ¬Έμ κ°κ²©μ λΆλ¬μ€κ³ μλ€. μ£Όλ¬Έ ν μ£Όλ¬Έν μ¬λμκ² μμμ¦μ λ°νν΄μ£Όλ κ²κ³Ό λ§μ°¬κ°μ§μ μν©μΌλ‘ μκ°ν μλ μλ€.
μ΄ μ½λ μνμ€λ₯Ό 2κ°μ μ°λ λ T1κ³Ό T2κ° μ κ·Όνλ€κ³ κ°μ νμ. κ·Έλ¦¬κ³ μ΄μ§Έμ μ§Έ μ¬λ¬ μ€μΌμ€λ§κ³Ό μμΈμ λ°λΌμ μ€ν μμκ° λ€μκ³Ό κ°μ΄ λλ€κ³ μκ°ν΄λ³΄μ.
T1.order('μμ²λ λΆμ', 100000000);
T2.order('μ‘°κΈ λΆμ', 100);
T1.getPrice();
T2.getPrice();
κ·Έλ¬λ©΄ μ΄λ»κ² λ κΉ? μμ²λ λΆμμκ²λ 1μ΅μμ μμμ¦μ΄ λ°κΈλμ΄μΌ νλ€. νμ§λ§ μ‘°κΈ λΆμ μ°λ λκ° μ€κ°μ λ€μ΄μμ StatefulService μ priceλ₯Ό 100μμΌλ‘ λ³κ²½ν΄λ²λ Έλ€. λ°λΌμ μμ²λ λΆμμ μ‘°κΈ λΆμ λ λ€ 100μμ μμμ¦μ λ°κΈλ°κ² λλ€. μ μ 2λͺ μ μν©λ§ ν΄λ μ΄λ κ² μ΄μ§λ¬μ΄λ°, λ§μ½ μ΄λΉ νΈλν½μ΄ 1λ§μΈ μ€μ μλΉμ€μμ μ΄λ° μΌμ΄ μΌμ΄λ¬λ€κ³ μκ°νλ©΄ κ·Έμ μ΄μ§λ½κΈ°λ§ νλ€. κ·Έλ₯ νμ¬ λ¬Έ λ«λκ±°λ€.
κ·ΈλΌ μ΄λ»κ²?
무쑰건 Stateless νκ² μ€κ³ν΄μΌ νλ€. global νκ² μ κ·Όν μ μλ stateλ₯Ό μ λ λ§λ€μ§ λ§μ.
μ¬λ¬ μ°λ λκ° νλμ μμμ μ κ·Όνλ μν©μ λ§μ§ λͺ»νλ©΄ μ¬κ°ν λ¬Έμ μ λλ¬ν μ μλ€.
κ°μΈμ μΌλ‘λ ThreadLocal λ±μ λ€λ₯Έ λ°©λ²μΌλ‘ λ¬Έμ λ₯Ό ν΄κ²°νκΈ°λ³΄λ€ μ μ΄μ ꡬ쑰λ₯Ό μ μ‘μμ λ¬Έμ λ₯Ό λ°μμν€μ§ μλ κ²μ΄ μ΅μ μΈ κ² κ°λ€.
μ¬μ€ μ΄κ²μ λΉλ¨ μ±κΈν€μ λ¬Έμ λΏ μλλΌ, http κ·Έλ¦¬κ³ REST νκ²½μμλ λ§μ°¬κ°μ§μ΄λ€. μ΄ νκ²½μμμ μλΉμ€λ Scale out μν© λ±μ κ³ λ €νμ λμλ Stateless νκ² μ€κ³νλ κ²μ΄ μ μμΌλ‘ μλ €μ Έ μλ€.
@Configurationκ³Ό μ±κΈν€, κ·Έλ¦¬κ³ CGLib
κ°μΈμ μΌλ‘ μ΄ λΆλΆμ μμ΄μ μμ£Ό κΆκΈν¨μ΄ λ§μλ€. κ°μ μμμ μ€μ΅νλ©° μμ±ν μ½λμ μνλ©΄ λμ ν μΌλ°μ μΈ μ€ν μμλ‘λ μ΄ν΄ν μ μλ λΆλΆμ΄ μλμκΈ° λλ¬Έμ΄λ€. κ·Έλ¦¬κ³ κ·Έ ν΄κ²°λ²μ λν΄μλ κ΅μ₯ν λ¬ν ν΄κ²°μ± μ΄λΌλ μκ°μ νλ€.
λκ° μ΄μνλ―ν AppConfig
κ°μμμ λμ€λ μμ μ½λλ₯Ό 볡λΆνλ νμλ₯Ό μ΅λν λ°°μ νλ €κ³ μ κ²½μ°κ³ μμ§λ§, AppConfigμ κ²½μ°μ κ΅μ₯ν μΌλ°μ μ΄κΈ° λλ¬Έμ κ·Έλλ‘ μ¬μ©νλλ‘ νκ² λ€.
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
@Bean
public OrderService orderService() {
return new OrderServiceImpl(
memberRepository(),
discountPolicy());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
// ...rest
}
μ΄ μ½λλ₯Ό 보면 memberRepository()
κ° μΈλΆ Beanμμ μ£Όμ
μ μν΄ 2λ² νΈμΆλλ κ²μ λ³Ό μ μλ€.
memberService()
μμorderService()
μμ
κ°κ° νΈμΆλμ΄ 2λ² νΈμΆλλ€.
μ΄μ λνμ¬, μ μ΄μ MemberRepository
μ λν μ€μ μ νκΈ° μν΄ μ€νλ§ μ»¨ν
μ΄λκ° κ΅¬λλλ©΄μ @Bean
μ΄λ
Έν
μ΄μ
μ μΈμνμ¬ μ²μμ 1λ² νΈμΆλλ€.
νμ§λ§ μ°λ¦¬λ μμμ μΈκΈνλ―, μ€νλ§ μ»¨ν
μ΄λλ₯Ό λ―ΏκΈ° λλ¬Έμ ν΄λμ€λ₯Ό μμ±ν λ λ³λλ‘ μ±κΈν€ ν¨ν΄μ ꡬννκΈ° μν μ½λλ₯Ό μμ±νμ§ μμλ€. κ·Έλ λ€λ©΄ memberRepository()
λ μ€ν μμ μ λΆλͺ
3λ² μ€νλλ€.
μΌλ°μ μΈ μλ° λ°νμμ μνλ©΄ λ°λΌμ κ°κ°μ memberRepository()
λ κ°κ°μ MemoryMemberRepository
μΈμ€ν΄μ€λ₯Ό λ°νν΄μΌ νκ³ , μ΄μ λ°λΌ μ±κΈν€ ν¨ν΄μ μ§ν€μ§ λͺ»νκ² λλ€. νμ§λ§ μ€νλ§ μ»¨ν
μ΄λλ μ΄ μΈμ€ν΄μ€λ€μ΄ λͺ¨λ κ°μ μ±κΈν€ μΈμ€ν΄μ€μμ 보μ₯νλ€. μ΄κ²μ΄ μ΄λ»κ² κ°λ₯νκ±ΈκΉ?
CGLIBκ³Ό λ°μ΄νΈ μ½λ μ‘°μ
μμ μ½λλ₯Ό μ€λͺ
νλ©΄μ μ§μ§ μκ³ λμ΄κ° νλμ μ΄λ
Έν
μ΄μ
μ΄ μλ€. λ°λ‘ @Configuration
μ΄λ€.
κΉμ§κ² λλ°? κ·Έλ₯ μ€μ ν΄λμ€λΌλκ±° μλμΌ? λΌκ³ μκ°νμλ€. κ·Έλ°λ°, μκ°ν΄λ³΄λ©΄ νλ μμν¬ κ·Έλ¦¬κ³ DI, IoC λΌλ κ΄μ μμ μ€μ μ κ·Έ μμ²΄λ‘ κ΅μ₯ν μ€μν μλ―Έλ₯Ό κ°μ§κ³ μλ€. μ΄ μ€μ μ κΈ°λ°μΌλ‘ νλ‘μ νΈκ° νλ μμν¬ μμμ ꡬλμ΄ λκΈ° λλ¬Έμ΄λ€. κ·Έλ¬λ©΄ μ΄ @Configuration
μ μ±κΈν€ 컨ν
μ΄λλΌλ λ¬Έλ§₯μμλ μ΄λ€ μν μ νκ³ μμκΉ?
@Configuration
μ΄ λΆμ ν΄λμ€λ μ€νλ§ μ»¨ν
μ΄λμλ νλμ μ€νλ§ λΉ(Spring Bean)μΌλ‘ λ±λ‘λλ€. κ·Έλ°λ°, μ΄ ν΄λμ€λ μ€νλ§ μ»¨ν
μ΄λμ κ³§μ΄ κ³§λλ‘ μμ μ μΈμ€ν΄μ€κ° λ±λ‘λλ κ²μ΄ μλλΌ, CGLIBμ ν΅ν΄μ λ°μ΄νΈ μ½λκ° μ‘°μλ ν΄λμ€(**.*.AppConfig$$EnhancerBySpringCGLIB$$somehash
)κ° μΈμ€ν΄μ€λ‘ λ±λ‘λλ€. (μ°Έκ³ λ‘ λ°μ΄νΈ μ½λκ° μ‘°μλ ν΄λμ€λ μλ AppConfig
ν΄λμ€λ₯Ό μμνμκΈ° λλ¬Έμ AppConfig
λ₯Ό μ΄μ©ν΄μ μ€νλ§ μ»¨ν
μ΄λλ‘λΆν° μ‘°νν΄μ¬ μ μλ€.)
μ΄λ κ² λ°μ΄νΈ μ½λκ° μ‘°μλ AppConfig
λ λ΄λΆμ μ€μ λμ΄ μλ μ€νλ§ λΉμ κ°μ Έμ¬ λ, μ€νλ§ μ»¨ν
μ΄λμ μ΄λ―Έ λ±λ‘λ κ²½μ°κ° μμλμ§λ₯Ό ν λ² λ νμΈνλ μ μ°¨λ₯Ό κ°μ§κ² λλ€. μμΌλ©΄ μμ±νκ³ , μμΌλ©΄ μλ κ²μ κ·Έλλ‘ κ°μ Έλ€ μ°λ, κ·ΈμΌλ§λ‘ λ°μ΄νΈ μ½λ μ‘°μμ ν΅ν΄μ μ±κΈν€ ν¨ν΄μ κ°μ λ‘ κ΅¬ννλ κ²μ΄λ€.
μ€μ λ‘, @Configuration
μ΄λ
Έν
μ΄μ
μ΄ μλ μνλ‘ μμ μ½λλ₯Ό μ€ννλ©΄, μΌλ°μ μΈ μλ° λ°νμμμμ μ€ν λ©μ»€λμ¦λλ‘ 3κ°μ MemoryMemberRepository
μΈμ€ν΄μ€κ° μ€νλ§ μ»¨ν
μ΄λμ λ±λ‘λλ€.
μ΄λ»κ² 보면 κΈ°νμΌλ‘ 보μ΄λλ°β¦
μ²μμ μ΄ λ°©μμ λ³΄κ³ μ κ΅μ₯ν κΈ°νμ΄λΌλ μκ°μ νλ€. κ·Έλ μ§λ§, μλ°μμ μ±κΈν€ ν¨ν΄μΌλ‘ ν΄λμ€λ₯Ό μ μΈν κ²½μ° μκΈ°λ λ¨μ μ λν΄μ μκ°νκ³ λ ν΄λΉ λ°©μμ λν΄μ λ©λνκ² λμλ€.
μ λΆλΆμμ κΈ°μ ν μ±κΈν€ ν¨ν΄μ μλ° μ½λλ‘ κ΅¬νν κ²½μ° μκΈ°λ λ¨μ λ€μ ν΄λμ€μ μ¬λ¬κ°μ§ λμμΈ ν¨ν΄μ μ μ©νκΈ° μ΄λ ΅κ² λ§λ€κ³ , λ¨μ ν μ€νΈλ μννκΈ° μ΄λ ΅κ² λ§λ λ€. λν κ°μ λ‘ κ΅¬ν체μ μμ‘΄νκ² λκΈ° λλ¬Έμ DIP, OCPλ μλ°°νκ² λλ€.
μ μ§λ³΄μνκΈ° μ’μ μννΈμ¨μ΄λ₯Ό κ°λ°ν μ μκ² νκΈ° μν΄μλ μ΄λ¬ν λ¬Έμ λ€μ λ°λμ ν΄κ²°ν΄μΌ νμ κ²μ΄λ€. μ΄μ λν ν΄κ²°μ± μΌλ‘ μ€νλ§ κ°λ°μλ€μ Proxy κ°μ²΄λ₯Ό λ§λλ κ²μ μ ννλ€. νμ§λ§ Java Dynamic Proxyλ λ°λμ μΈν°νμ΄μ€λ₯Ό ꡬννλ ν΄λμ€μ λν΄μλ§ Reflectionμ μ΄μ©ν΄μ Proxy κ°μ²΄λ₯Ό μμ±ν΄μΌ νκΈ° λλ¬Έμ μ΄λ¬ν μν©μλ μ ν©νμ§ μλ€.
λ°λΌμ, ν΄λμ€λ§μΌλ‘λ Proxy κ°μ²΄λ₯Ό μμ±ν μ μλ CGLIBμ μ νν κ²μ΄λΌκ³ λ©λνκ² λμλ€.
μμ§ AOPλ Java Reflection, Proxy ν¨ν΄μ λν μ΄ν΄κ° μ½νκΈ° λλ¬Έμ μ ννμ§λ μμ μ μμ΅λλ€. λκΈλ‘ μλͺ»λ λΆλΆμ΄ μμΌλ©΄ κΌ μ§μ ν΄μ£ΌμΈμ! μμΌλ‘ κΎΈμ€ν 곡λΆν΄μ, μλ²½ν μ΄ν΄λ₯Ό ν λ€μ κ³ μΉλλ‘ νκ² μ΅λλ€.
κ²°λ‘ μ
ν¬κ² κ³ λ―Όν νμκ° μλ€.
μΌλ¨ μ΄ μ λ μ΄ν΄λλ‘ κ°λ°μ ν΄μΌ νλ μν©μ΄λΌλ©΄ κ·Έλ₯ @Configuration
μ΄λ
Έν
μ΄μ
μ μ¬μ©νλλ‘ νμ.
λ€μμ
μ΄μ, μ€νλ§μ μ±κΈν€ 컨ν μ΄λμ λν λ΄μ©λ€μμ μ€μνλ€κ³ λλ λΆλΆλ€μ κ°λ΅ν μ λ¦¬ν΄ λ³΄μλ€. μ΄ λΆλΆμ λν΄μ μ νν μ΄ν΄νκΈ° μν΄μλ λ 곡λΆν΄μΌ νλ λ΄μ©μ΄ λ§λ€κ³ λλλ€. AOPλ Proxy ν¨ν΄μ λν΄μ 곡λΆνλ κ²μ λ¬Όλ‘ μ΄κ³ , μ€μ λ‘ μ΄λ¬ν ννλ‘ μ½λλ₯Ό μμ±νμ λ μ¬λ¬κ°μ§ λμμΈ ν¨ν΄μ μ μ©νκ±°λ μλλ©΄ ν μ€νΈλ₯Ό μμ±νλ λ°μ μ΄λμ΄ μλμ§λ₯Ό λ껴보λ κ²μ΄ μ€μνλ€λ μκ°μ΄ λ λ€.
λ€μ ν¬μ€νΈμμλ μ»΄ν¬λνΈ μ€μΊμ λν λ΄μ©μ λ€λ€λ³΄λλ‘ νκ² λ€.
λ.