From 46f6fb5596594acd0db4e005ad7440ec037588e5 Mon Sep 17 00:00:00 2001 From: haerong22 Date: Thu, 7 Oct 2021 00:59:36 +0900 Subject: [PATCH] spring core : Dependency Injection --- spring-core/basic/build.gradle | 10 ++++ .../java/com/example/basic/AutoAppConfig.java | 3 +- .../basic/annotation/MainDiscountPolicy.java | 13 +++++ .../basic/discount/FixDiscountPolicy.java | 4 ++ .../basic/discount/RateDiscountPolicy.java | 6 +++ .../example/basic/order/OrderServiceImpl.java | 6 ++- .../example/basic/autowired/AllBeanTest.java | 52 +++++++++++++++++++ .../basic/autowired/AutowiredTest.java | 36 +++++++++++++ .../basic/order/OrderServiceImplTest.java | 24 +++++++++ .../example/basic/scan/AutoAppConfigTest.java | 9 +++- 10 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 spring-core/basic/src/main/java/com/example/basic/annotation/MainDiscountPolicy.java create mode 100644 spring-core/basic/src/test/java/com/example/basic/autowired/AllBeanTest.java create mode 100644 spring-core/basic/src/test/java/com/example/basic/autowired/AutowiredTest.java create mode 100644 spring-core/basic/src/test/java/com/example/basic/order/OrderServiceImplTest.java diff --git a/spring-core/basic/build.gradle b/spring-core/basic/build.gradle index 78a36270..5f90e2d4 100644 --- a/spring-core/basic/build.gradle +++ b/spring-core/basic/build.gradle @@ -14,9 +14,19 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter' + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' } test { useJUnitPlatform() } + +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} diff --git a/spring-core/basic/src/main/java/com/example/basic/AutoAppConfig.java b/spring-core/basic/src/main/java/com/example/basic/AutoAppConfig.java index ae1e262e..e07b21c4 100644 --- a/spring-core/basic/src/main/java/com/example/basic/AutoAppConfig.java +++ b/spring-core/basic/src/main/java/com/example/basic/AutoAppConfig.java @@ -13,9 +13,10 @@ import org.springframework.context.annotation.FilterType; excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class) ) public class AutoAppConfig { - +/* @Bean(name = "memoryMemberRepository") // 수동 빈, 자동 빈 이름 같을 경우 수동 빈이 우선순위를 가진다.( 최근 스프링 부트는 에러 ) MemberRepository memberRepository() { return new MemoryMemberRepository(); } +*/ } diff --git a/spring-core/basic/src/main/java/com/example/basic/annotation/MainDiscountPolicy.java b/spring-core/basic/src/main/java/com/example/basic/annotation/MainDiscountPolicy.java new file mode 100644 index 00000000..fe910e72 --- /dev/null +++ b/spring-core/basic/src/main/java/com/example/basic/annotation/MainDiscountPolicy.java @@ -0,0 +1,13 @@ +package com.example.basic.annotation; + +import org.springframework.beans.factory.annotation.Qualifier; + +import java.lang.annotation.*; + +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +@Documented +@Qualifier("mainDiscountPolicy") +public @interface MainDiscountPolicy { +} diff --git a/spring-core/basic/src/main/java/com/example/basic/discount/FixDiscountPolicy.java b/spring-core/basic/src/main/java/com/example/basic/discount/FixDiscountPolicy.java index e61c2a85..370bc882 100644 --- a/spring-core/basic/src/main/java/com/example/basic/discount/FixDiscountPolicy.java +++ b/spring-core/basic/src/main/java/com/example/basic/discount/FixDiscountPolicy.java @@ -2,7 +2,11 @@ package com.example.basic.discount; import com.example.basic.member.Grade; import com.example.basic.member.Member; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; +@Component +@Qualifier("fixDiscountPolicy") public class FixDiscountPolicy implements DiscountPolicy { private final int discountFixAmount = 1000; diff --git a/spring-core/basic/src/main/java/com/example/basic/discount/RateDiscountPolicy.java b/spring-core/basic/src/main/java/com/example/basic/discount/RateDiscountPolicy.java index 2452f347..36d9abe2 100644 --- a/spring-core/basic/src/main/java/com/example/basic/discount/RateDiscountPolicy.java +++ b/spring-core/basic/src/main/java/com/example/basic/discount/RateDiscountPolicy.java @@ -1,10 +1,16 @@ package com.example.basic.discount; +import com.example.basic.annotation.MainDiscountPolicy; import com.example.basic.member.Grade; import com.example.basic.member.Member; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; @Component +@MainDiscountPolicy +//@Qualifier("mainDiscountPolicy") // @Primary 보다 우선순위가 높다. +//@Primary public class RateDiscountPolicy implements DiscountPolicy { private final int discountPercent = 10; diff --git a/spring-core/basic/src/main/java/com/example/basic/order/OrderServiceImpl.java b/spring-core/basic/src/main/java/com/example/basic/order/OrderServiceImpl.java index 4502d5f4..0a4f4786 100644 --- a/spring-core/basic/src/main/java/com/example/basic/order/OrderServiceImpl.java +++ b/spring-core/basic/src/main/java/com/example/basic/order/OrderServiceImpl.java @@ -1,19 +1,23 @@ package com.example.basic.order; +import com.example.basic.annotation.MainDiscountPolicy; import com.example.basic.discount.DiscountPolicy; import com.example.basic.member.Member; import com.example.basic.member.MemberRepository; +import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @Component +//@RequiredArgsConstructor public class OrderServiceImpl implements OrderService { private final MemberRepository memberRepository; private final DiscountPolicy discountPolicy; @Autowired - public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) { + public OrderServiceImpl(MemberRepository memberRepository, @MainDiscountPolicy DiscountPolicy discountPolicy) { this.memberRepository = memberRepository; this.discountPolicy = discountPolicy; } diff --git a/spring-core/basic/src/test/java/com/example/basic/autowired/AllBeanTest.java b/spring-core/basic/src/test/java/com/example/basic/autowired/AllBeanTest.java new file mode 100644 index 00000000..4c44f736 --- /dev/null +++ b/spring-core/basic/src/test/java/com/example/basic/autowired/AllBeanTest.java @@ -0,0 +1,52 @@ +package com.example.basic.autowired; + +import com.example.basic.AutoAppConfig; +import com.example.basic.discount.DiscountPolicy; +import com.example.basic.member.Grade; +import com.example.basic.member.Member; +import org.assertj.core.api.Assertions; +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 java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.*; + +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); + + int rateDiscountPrice = discountService.discount(member, 20000, "rateDiscountPolicy"); + assertThat(rateDiscountPrice).isEqualTo(2000); + } + + static class DiscountService { + private final Map policyMap; + private final List policies; + + @Autowired + public DiscountService(Map policyMap, List 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); + return discountPolicy.discount(member, price); + } + } +} diff --git a/spring-core/basic/src/test/java/com/example/basic/autowired/AutowiredTest.java b/spring-core/basic/src/test/java/com/example/basic/autowired/AutowiredTest.java new file mode 100644 index 00000000..296abc3c --- /dev/null +++ b/spring-core/basic/src/test/java/com/example/basic/autowired/AutowiredTest.java @@ -0,0 +1,36 @@ +package com.example.basic.autowired; + +import com.example.basic.member.Member; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.lang.Nullable; + +import java.util.Optional; + +public class AutowiredTest { + + @Test + void autowiredOption() { + AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(TestBean.class); + + } + + static class TestBean { + + @Autowired(required = false) + public void setNoBean1(Member noBean1) { + System.out.println("noBean1 = " + noBean1); + } + + @Autowired + public void setNoBean2(@Nullable Member noBean2) { + System.out.println("noBean2 = " + noBean2); + } + + @Autowired + public void setNoBean3(Optional noBean3) { + System.out.println("noBean3 = " + noBean3); + } + } +} diff --git a/spring-core/basic/src/test/java/com/example/basic/order/OrderServiceImplTest.java b/spring-core/basic/src/test/java/com/example/basic/order/OrderServiceImplTest.java new file mode 100644 index 00000000..087364ec --- /dev/null +++ b/spring-core/basic/src/test/java/com/example/basic/order/OrderServiceImplTest.java @@ -0,0 +1,24 @@ +package com.example.basic.order; + +import com.example.basic.discount.FixDiscountPolicy; +import com.example.basic.member.Grade; +import com.example.basic.member.Member; +import com.example.basic.member.MemoryMemberRepository; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.*; + +class OrderServiceImplTest { + + @Test + void createOrder() { + MemoryMemberRepository memberRepository = new MemoryMemberRepository(); + memberRepository.save(new Member(1L, "name", Grade.VIP)); + + OrderServiceImpl orderService = new OrderServiceImpl(new MemoryMemberRepository(), new FixDiscountPolicy()); + Order order = orderService.createOrder(1L, "itemA", 10000); + + assertThat(order.getDiscountPrice()).isEqualTo(1000); + } +} \ No newline at end of file diff --git a/spring-core/basic/src/test/java/com/example/basic/scan/AutoAppConfigTest.java b/spring-core/basic/src/test/java/com/example/basic/scan/AutoAppConfigTest.java index 1d78d3a7..547ae475 100644 --- a/spring-core/basic/src/test/java/com/example/basic/scan/AutoAppConfigTest.java +++ b/spring-core/basic/src/test/java/com/example/basic/scan/AutoAppConfigTest.java @@ -1,12 +1,13 @@ package com.example.basic.scan; import com.example.basic.AutoAppConfig; +import com.example.basic.member.MemberRepository; import com.example.basic.member.MemberService; -import org.assertj.core.api.Assertions; +import com.example.basic.order.OrderServiceImpl; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; class AutoAppConfigTest { @@ -16,5 +17,9 @@ class AutoAppConfigTest { MemberService memberService = ac.getBean(MemberService.class); assertThat(memberService).isInstanceOf(MemberService.class); + + OrderServiceImpl bean = ac.getBean(OrderServiceImpl.class); + MemberRepository memberRepository = bean.getMemberRepository(); + System.out.println("memberRepository = " + memberRepository); } }