30%
61,600원
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결스프링 핵심 원리 - 기본편
main에서 코드실행시 gradle에서 빌드되는거같아요 ㅠ
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요강의잘듣고있습니다!Main에서 코드실행시 스프링 로딩되면서 로그가 보여야하는데, 뭔가 Gradle 실행된는것같아요구글링해서 찾아봣는데 해결법을 찾을수가없어서 질문드립니다!메인 실행시 아래 화면처럼 나옵니다!확인부탁드립니다!
- 미해결스프링 핵심 원리 - 기본편
UnsatisfiedDependencyException와 NoUniqueBeanDefinitionException의 차이점
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 안녕하세요 영한 쌤. @Autowired 시 동일한 타입의 빈이 2개 이상일 때를 확인하고 있던 중, 강의와는 다른 에러가 나와서 질문 드립니다. 강의에서는 현재 NoUniqueBeanDefinitionException 에러가 발생하고 있는데 저는 UnsatisfiedDependencyException 라는 에러가 발생합니다.NoUniqueBeanDefinitionException 의 경우에 동일한 타입의 빈이 중복으로 존재한다는 의미이고, UnsatisfiedDependencyException 의 경우에는 의존성이 들어오고 있지 않는 것이 문제라고 알고 있었습니다. 하지만 현재 매칭되는 빈이 2개라는 에러 메세지가 발생하며 UnsatisfiedDependencyException 에러가 발생했고, 두 에러의 차이점을 명확히 하고 싶어 문의를 드립니다. 두 에러가 같은 상황에서 혼용될 수 있는 에러인가요? org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'orderServiceImpl' defined in file [/Users/wooruk/workspace/younghan/spring/core/out/production/classes/com/hello/core/order/OrderServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 1: No qualifying bean of type 'com.hello.core.discount.DiscountPolicy' available: expected single matching bean but found 2: fixDiscountPolicy,rateDiscountPolicy
- 해결됨스프링 핵심 원리 - 기본편
assertThat() 인자값 질문있습니다.
assertThat() 메서드에 대해서 찾아 봤는데, 매개변수 이름이 actual(실제값) 이더라구요. 그리고 isEqualTo() 메서드의 매개변수 이름은 expected(기대값)이구요.그러면 assertThat() 메서드를 호출할 때 인자값으로 테스트하고자 하는 값을, 그리고 isEqualTo() 메서드는 테스트의 결과로 기대되는 값을 넘기는게 맞지 않나요?여기 아래 코드에서 memberService.findMember(1L)로 찾아온 회원(findMember)이앞서 직접 만들어서 join으로 넘긴 member와 같아야 하는 거니까Assertions.assertThat(findMember).isEqualTo(member)가 맞는거 아닌가요?
- 미해결스프링 핵심 원리 - 기본편
컴포넌트 스캔시 빈이름 질문
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]컴포넌트 스캔시 빈 이름이 자동으로 구현된 클래스의 이름으로 설정되게 되는데요. 이 경우 DIP 위반과는 상관없는 건가요?? 예를 들어 memoryMemberRepository 처럼요.물론 타입으로 조회 시에는 MemberRepositoy.class로 조회가능하지만, 이름으로 조회시에는 클래스명(앞에 소문자)로 조회해야 되서요. 공부중 궁금해져서 질문 드립니다.
- 미해결스프링 핵심 원리 - 기본편
싱글톤 @Configuration
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]class StatefulServiceTest { @Test void statefulServiceSingleton() { ApplicationContext ac = new AnnotationConfigApplicationContext(TestConfig.class); StatefulService statefulService1 = ac.getBean(StatefulService.class); StatefulService statefulService2 = ac.getBean(StatefulService.class); // Thread A : A 사용자 10000원 주문 // statefulService1.order("userA", 10000); int userAPrice = statefulService1.order("userA", 10000); // Thread B : B 사용자 10000원 주문 // statefulService2 .order("userB", 20000); int userBPrice = statefulService2.order("userB", 20000); // Thread A : A 사용자 주문 금액 조회 // int price = statefulService1.getPrice(); // System.out.println("price = " + price); System.out.println("userAPrice = " + userAPrice); System.out.println("userBPrice = " + userBPrice); } static class TestConfig { @Bean public StatefulService statefulService() { return new StatefulService(); } } }이 코드에서 TestConfig는 @Configuration 어노테이션을 붙이지 않았는데 어떻게 싱글톤이 보장된건가요?
- 미해결스프링 핵심 원리 - 기본편
등록된 bean 2개 이상일때 타입의 명칭 질문
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]여기에 질문 내용을 남겨주세요. basicScan Test시 아래처럼 조회된 bean 2개 이상실때 명칭을 달리하면 해결된다고 하셨는데요.OrderServiceImpl에서 아래처럼 DiscountPolicy 명칭을 rateDisCountPolicy로 수정 하면 위와 같은 동일한 이슈가 발생되는걸 확인 했습니다. 그래서 명칭의 대소문자를 @Component 통해 등록된 rateDiscountPolicy로 변경했더니 정상적으로 테스트가 진행 됬는데요. 이유가 뭔가요?타입 명칭을 등록된 bean 명칭과 동일하게 해야하는건가요?혼란이 와서요 오류난 코드정상 작동 코드
- 미해결스프링 핵심 원리 - 기본편
테스트실행시 에러 "No matching tests found in any candidate test task."
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]테스트실행시 이런오류가 뜨네요.
- 미해결스프링 핵심 원리 - 기본편
Execution failed for task ':CoreApplication.main()' 오류질문
Execution failed for task ':CoreApplication.main()'.> Process 'command 'C:\Program Files\Java\jdk-17\bin\java.exe'' finished with non-zero exit value 1이런 오류가 뜹니다. 처음에 gradel 이 IntelliJ 로 되어 있을 때 빨간 오류는 아니었지만 Parameter 0 of constructor in hello.core.member.MemberServiceImpl required a single bean, but 2 were found: - memoryMemberRepository: defined in file [C:\SpringStudy\core\out\production\classes\hello\core\member\MemoryMemberRepository.class] - memberRepository: defined by method 'memberRepository' in class path resource [hello/core/AppConfig.class] 이런 에러가 나서 gradel을 Gradle(Default) 로 변경하였더Execution failed for task ':CoreApplication.main()'.> Process 'command 'C:\Program Files\Java\jdk-17\bin\java.exe'' finished with non-zero exit value 1 이런 오류가 납니다. 어떤 부분을 수정해야 하는 걸까요??
- 미해결스프링 핵심 원리 - 기본편
java, spring, gradle 최신버전 사용하시는 분들 lombok 설정 방법(질문x)
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]질문은 아닙니다.강의 복습 도중에 최신버전 이슈로 인하여 lombok 설정시 이슈나는 분들에게 공유 드리고자 합니다. 작성자 개발 환경java ver.17spring boot ver.3.2.3gradle ver.8.5강의 내용을 따라하시다가 위와 같은 오류가 발생되는 분들은 gradle 최신 버전부터는 메소드명이 바뀌었기 때문이니 코드를 아래와 같이 설정하시고 gradle reload 하시면 정상적으로 적용되는거 확인 하실 수 있습니다. * 최신버전의 gradlecompile() 메소드 대신 implementation() 메소드를 사용으로 변경 조금이나마 도움되시길 바랍니다.
- 미해결스프링 핵심 원리 - 기본편
"싱글톤방식의 주의점"강의와 이번강의의 내용이 헷갈립니다
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예[질문 내용]안녕하세요 예전 강의(싱글톤방식의 주의점 ) 에서 싱글톤객체 사용시 공유되는 전역변수를 사용하면 문제가 되므로 사용하면 안된다고 이해했습니다.(싱글톤객체는 여러 쓰레드에 의해 공유되므로 )이번 강의 에서 싱글톤객체의 필드에 프로토타입 스코프의 객체를 주입받아서 사용하는데 이 객체가 프로토타입스코프여서 문제가 되는게 아니라 해당 객체의 전역변수를 변경하는 로직이 문제가 되는거 아닌가요? 주입받는 객체가 프로토타입 스코프가 아니라 싱글톤스코프여도 여러스레드에 의해 공유되는 전역변수를 변경하는 로직이 문제가 되는건 아닌지요. 싱글톤사용시 공유되는 전역변수를 변경하는 로직을 사용하면 안되다고 이해했는데 이번강의 에서는 싱글톤 객체에 주입받는 객체가 프로토타입스코프여서 문제가 되는걸로 이해가 잘되질않아서요. 질문이 너무 두서가 없는것 같지만 해당부분이 잘이해가 안됩니다.ㅜ
- 해결됨스프링 핵심 원리 - 기본편
다른 요구사항에 대한 DiscountPolicy 설계 질문
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]안녕하세요? 좋은 강의 감사한 마음으로 잘 듣고 있습니다. DiscountPolicy에 새로운 구현체를 추가하는 방법으로 유연하게 기능을 확장하는 예시를 잘 보았습니다. 그런 중 궁금한 점이, 지금 DiscountPolicy.discount 메서드는 Member형과 int형을 매개변수로 받고 있습니다.그런데 만약 다른 형의 자료가 필요한 discountPolicy를 만드려면 어떻게 설계하는 것이 좋을까요?예를 들어 itemName(String)을 기반으로 하는 할인 정책이 필요한 경우라면 어떻게 변경하는 것이 좋을지 궁금합니다. 제가 생각한 것은1) Generic DiscountPolicy 인터페이스를 만든다? public interface GenericDiscountPolicy<T> { int discount (T type, int price); } 2) 인터페이스 서명을 바꾼다?public interface DiscountPolicy { int discount (Member member, String itemName, int price); } 1) Generic으로 인터페이스를 만들면 interface를 사용하는 client에서 generic type을 지정해야 해서 다른 변경에 유연하지 않아 보입니다.2) 새로운 할인 정책 요소가 생길 때마다 매개 변수를 계속 늘리는 것은 바람직하지 않아 보입니다. 다형성을 이용한 유연한 설계라는 주제에 조금 벗어나는 것 같지만 유연하게 설계하기 위해 어떻게 객체지향 원리를 적용할 수 있는지 궁금합니다. 오늘도 좋은 하루 보내시길 바랍니다. 감사합니다! 🙏
- 미해결스프링 핵심 원리 - 기본편
clientBean 은 프로토타입 빈의 참조값을 보관하는거 있잖아요
ApplicationContext ac = new AnnotationConfigApplicationContext(ClientBean.class, PrototypeBean.class); ClientBean clientBean = ac.getBean(ClientBean.class); clientBean 이 prototypeBean 을 바로 참조하는게 아니라clientBean 에 생성된 prototypeBean 참조하면 그 안에생성 시점에 주입 받은 참조 값을 참조하는 건가요?맞나요? 헷갈려요 ㅠ
- 미해결스프링 핵심 원리 - 기본편
초기화 관련 질문
강의 자료 중 초기화에 대한 언급이 나와서 완벽한 감이 안잡혀서 질문을 드립니다.강의 영상 중 초기화는 객체가 일을 시작하는 것이라고 하셨는데 이 일을 시작한다는 말이 정확하게 와닫지 않아서 질문을 드립니다,, 감사합니다..
- 해결됨스프링 핵심 원리 - 기본편
UnsatisfiedDependencyException에러가 안잡힙니다.
[질문 내용]여기에 질문 내용을 남겨주세요.https://drive.google.com/file/d/1fuxg2PcUZOT1bxTbwcTS5ZLdbO-Iz_M5/view?usp=drive_link현재 제 프로젝트 압축파일을 구글 드라이브에 업로드했습니다. 현재 듣고 있는 강의는 섹션7. 조회한 빈이 모두 필요할 때, List,Map입니다.듣고 있는 부분은 8분34초 입니다. https://www.inflearn.com/questions/1089023/이 답변을 참고해서 해결방안 2, 해결방안 3을 모두 적용해봤지만 오류가 해결되지 않고있습니다.어떤작업을 해야할까요..?
- 미해결스프링 핵심 원리 - 기본편
findAllBean 테스트 오류(member를 빈으로 등록하라는 오류)
[질문 내용]여기에 질문 내용을 남겨주세요. 섹션 7의 조회한 빈이 모두 필요할 때, List, Map 강의 위치 => 05:02 @Autowired에 빨간 밑줄이 가서 다른 질문글을 찾아보고 DiscountService에 @Component 어노테이션을 달아줬습니다.그래도 똑같은 오류가 뜹니다. package hello.core.autowired.allbean; import hello.core.AutoAppConfig; import hello.core.discount.DiscountPolicy; import hello.core.member.Member; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.stereotype.Component; import java.util.List; import java.util.Map; public class AllBeanTest { @Test void findAllBean(){ AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class, DiscountService.class, Member.class ); } //기존 orderService를 수정하면 코드 수정하기 복잡해져서 테스트용 클래스 따로 만들음. @Component 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); } } }org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'member' defined in file [C:\Users\hotay\OneDrive\바탕 화면\study\core\core\build\classes\java\main\hello\core\member\Member.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type 'java.lang.Long' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
- 미해결스프링 핵심 원리 - 기본편
도메인 객체의 의존관계
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]appconfig로 의존관계를 주입해서 di를 진행하고, dip를 만족한다고 배웠습니다. 그런데 지금까지으 예제에서 service나 repository의 의존관계를 다루었지만 도메인은 다루지 않을 것같아서요.만일 member 도메인 객체가 주문 히스토리 데이터를 가져야할 때, order 도메인을 의존해야하면, 이때도 따로 도메인에 대한 interface를 만들고 appconfig를 이용해 의존관계를 주입하는지 궁금합니다.
- 미해결스프링 핵심 원리 - 기본편
test 오류를 못찾겠습니다..
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. https://drive.google.com/file/d/1eaGwuFK0ptwt7-5tXkKBmLXL6c_8wVCr/view?usp=drive_link
- 미해결스프링 핵심 원리 - 기본편
컴포넌트 스캔과 의존관계 자동 주입 제대로 이해한건지 궁금합니다!
[질문 내용]@Configuration 이 붙은 클래스는 스프링 컨테이너에 설정 정보를 의미하는것으로 @Configuration 이게 붙은 클래스도 싱글톤이 보장되어야 하기 때문에 @Bean으로 등록되어 싱글톤을 보장하고 자동주입의 경우에 빈 이름을 @Component 에노테이션이 붙은 클래스를 빈 이름으로, 실제 의존관계 주입이되는 반환 객체를 @AutoWried 에노테이션이 붙은 생성자로 주입되는게 맞을까요?!제 머릿속에 있는 걸 그려봤는데 저런식으로 되는게 맞을까요?!
- 미해결스프링 핵심 원리 - 기본편
빈 충돌이 일어나는 테스트 오류를 못잡겠습니다ㅠㅠ
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 아니오3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예[질문 내용]섹션7의 옵션처리 강의를 보며 테스트 코드를 같이 수정하고 있습니다.CoreApplication을 Run 했을 때 발생하는 오류입니다. *************************** APPLICATION FAILED TO START *************************** Description: Parameter 0 of constructor in hello.core.member.MemberServiceImpl required a single bean, but 2 were found: - memoryMemberRepository: defined in file [C:\Users\hotay\OneDrive\바탕 화면\study\core\core\out\production\classes\hello\core\member\MemoryMemberRepository.class] - memberRepository: defined by method 'memberRepository' in class path resource [hello/core/AppConfig.class] 이 부분을 보고 MemoryMemberRepository 와 AppConfig와 AutoAppConfig 코드를 봤는데 뭐가 문제인지 모르겠습니다.package hello.core.member; import org.springframework.stereotype.Component; import java.util.*; @Component //빈등록될때는 앞에가 소문자로, memoryMemberRepository로 등록된다. public class MemoryMemberRepository implements MemberRepository{ private static Map<Long, Member> store = new HashMap<>(); @Override public void save(Member member) { store.put(member.getId(),member); } @Override public Member findById(Long memberId) { return store.get(memberId); } }package hello.core; import hello.core.discount.DiscountPolicy; import hello.core.discount.FixDiscountPolicy; import hello.core.discount.RateDiscountPolicy; import hello.core.member.MemberService; import hello.core.member.MemberServiceImpl; import hello.core.member.MemoryMemberRepository; import hello.core.order.OrderService; import hello.core.order.OrderServiceImpl; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; //애플리케이션 전체 동작 방식을 구성(config)하기 위해 // 구현객체를 생성하고 연결하는 책임을 가지는 별도의 설정 클래스 //메서드마다 역할이 드러나게끔 한다. @Configuration //설정정보에 적어주는 어노테이션 public class AppConfig { @Bean //스프링 컨테이너에 등록이 된다. public MemberService memberService(){ return new MemberServiceImpl(memberRepository());//생성자 주입 //MemberServiceImpl이 필요로 하는 MemberRepository 의존성을 외부에서 주입 } @Bean public MemoryMemberRepository memberRepository() {//구현객체를 반환해주는 역할 return new MemoryMemberRepository(); } @Bean public OrderService orderService(){ return new OrderServiceImpl(memberRepository(),discountPolicy());//생성자 주입 } @Bean public DiscountPolicy discountPolicy(){ return new RateDiscountPolicy(); } } package hello.core; import hello.core.member.MemberRepository; import hello.core.member.MemoryMemberRepository; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; @Configuration //설정정보 어노테이션 @ComponentScan( basePackages = "hello.core", excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class)//AppConfig를 등록하지않도록 필터링 ) //컴포넌트 스캔 일일이 @bean 등록안해도됨 public class AutoAppConfig { //수동으로 빈을 등록하면 자동 빈보다 우선권을 가지게되어 오버라이딩 된다. (충돌오류X) //최근 스프링 부트에서는 수동 빈 등록과 자동 빈 등록이 충돌나면 오류가 발생하도록 기본 값을 바꾸었다. // application.properties에 spring.main.allow-bean-definition-overriding=true를 등록하면 오버라이딩 할 수 있다. /* @Bean(name = "memoryMemberRepository") public MemberRepository memberRepository() { return new MemoryMemberRepository(); }*/ } AutoAppConfig에 강사님 말씀 처럼 빈 충돌 테스트 한 부분을 주석처리해줬고 AppConfig를 등록하지 않도록 필터링 했는데도 어디에서 오류를 잡아야할지 모르겠습니다.
- 미해결스프링 핵심 원리 - 기본편
테스트 실패: Unsatisfied dependency expressed through field 'prototypeBeanProvider'
해당 오류입니다. org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'singletonWithPrototypeTest1.ClientBean': Unsatisfied dependency expressed through field 'prototypeBeanProvider': No qualifying bean of type 'javax.inject.Provider<hello.core.scope.SingletonWithPrototypeTest1$PrototypeBean>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 빈 주입이 안되어 오류가 나는 것 같아 @ComponentScan도 달아봤습니다. 빈을 못찾는다고 할까요package hello.core.scope;import jakarta.annotation.PostConstruct;import jakarta.annotation.PreDestroy;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.AnnotationConfigApplicationContext;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Scope;import org.springframework.stereotype.Component;import javax.inject.Provider;import static org.assertj.core.api.Assertions.*;@ComponentScanpublic class SingletonWithPrototypeTest1 {@Test void prototypeFind() {AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(PrototypeBean.class); PrototypeBean prototypeBean1 = ac.getBean(PrototypeBean.class); prototypeBean1.addCount(); assertThat(prototypeBean1.getCount()).isEqualTo(1); PrototypeBean prototypeBean2 = ac.getBean(PrototypeBean.class); prototypeBean2.addCount(); assertThat(prototypeBean2.getCount()).isEqualTo(1); }@Test void singletonClientUserPrototype(){// 스프링 컨텍스트를 생성하고 빈을 가져옴 AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(ClientBean.class, PrototypeBean.class); ClientBean clientBean1 = ac.getBean(ClientBean.class); int count1 = clientBean1.logic(); assertThat(count1).isEqualTo(1); ClientBean clientBean2 = ac.getBean(ClientBean.class); int count2 = clientBean2.logic(); assertThat(count2).isEqualTo(1); // 같은 count가 증가함 }@Scope("singleton")@Component static class ClientBean{// ObjectProvider를 통해 싱글톤 빈과 프로토타입을 함께 사용가능 @Autowired private Provider<PrototypeBean> prototypeBeanProvider; public int logic(){PrototypeBean prototypeBean = prototypeBeanProvider.get(); prototypeBean.addCount(); int count = prototypeBean.getCount(); return count; }}@Scope("prototype")@Component static class PrototypeBean {private int count = 0; public void addCount() {count++; }public int getCount(){return count; }@PostConstruct public void init(){System.out.println("PrototypeBean.init" + this); }@PreDestroy public void destroy(){System.out.println("PrototypeBean.destroy" + this); }}}