월 17,600원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결스프링 핵심 원리 - 기본편
스프링 부트를 쓰지 않는 단위 테스트의 모범 사례가 궁금합니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예[질문 내용]안녕하세요. 김영한님의 강의를 들으며 스프링 부트를 활용한 웹 어플리케이션 개발을 진행하고 있는데, 단위 테스트 코드 작성 시 모범 사례(?)가 있는지 궁금해 질문하게 되었습니다. 영한님의 강의에서 "좋은 테스트는 단위 테스트부터 출발하며, 단위 테스트를 잘 만드는 것이 좋은 테스트의 출발이다."라는 의미의 말을 기억하며 단위 테스트 코드를 다음과 같이 작성해보았습니다. AppConfig 코드@Configuration public class AppConfig { @Bean public MemberService memberService() { return new MemberServiceImpl(memberRepository()); } @Bean public MemberRepository memberRepository() { return new MemoryMemberRepository(); } // ... } 단위 테스트 대상 (서비스 컴포넌트)@Component public class MemberServiceImpl implements MemberService{ private final MemberRepository memberRepository; @Autowired public MemberServiceImpl(MemberRepository memberRepository) { this.memberRepository = memberRepository; } // ... } 위 서비스 컴포넌트를 단위 테스트 하기 위해 아래와 같은 테스트 코드를 작성했습니다.class MemberServiceImplTest { @Test @DisplayName("사례1") void case1() { // @SpringBootTest를 사용하진 않지만 ApplicationContext를 사용 ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class); // Bean 가져오기 MemberService memberService = ac.getBean(MemberService.class); MemberRepository memberRepository = ac.getBean("memberRepository", MemberRepository.class); // 가져온 것 확인하기 Assertions.assertThat(memberService).isInstanceOf(MemberService.class); Assertions.assertThat(memberRepository).isInstanceOf(MemberRepository.class); } @Test @DisplayName("사례2") void case2() { // 순수 자바로 가져오기 MemberRepository memberRepository = new MemoryMemberRepository(); MemberService memberService = new MemberServiceImpl(memberRepository); // 멤버 서비스 테스트 세팅 Member newMember = new Member(1L, "Test", Grade.VIP); memberService.join(newMember); // 멤버 서비스 테스트 검증 Member findMember = memberService.findMember(1L); Assertions.assertThat(newMember.getId()).isEqualTo(findMember.getId()); } }// 두 테스트 모두 테스트를 통과합니다.제가 궁금한 것은사례1은 과연 유닛 테스트라고 할 수 있을까요? @SpringBootTest를 붙여주지 않았을 뿐이지 스프링 컨테이너를 사용하기 때문에 유닛 테스트가 아닌 스프링 부트를 사용하는 통합 테스트라고 봐야하는거 아닌지 궁금합니다.사례2는 순수하게 자바로 인스턴스를 생성해 테스트를 진행합니다. 따라서 완전히 스프링에서 독립된 유닛 테스트라고 볼 수 있을 것 같습니다. 그런데 이 경우, 스프링의 도움을 받지 않기 때문에 의존성 주입을 직접 해줘야 한다는 점이 걸립니다. 따라서 사례2 처럼 직접 인스턴스를 선언하여 생성자로 주입해주는 것이 좋은 코드인지 의문이 듭니다.MemberServiceImpl 코드를 보면 생성자에 자동 의존 주입이 명시되어있는데, 만약 사례2처럼 생성할때 직접 수동으로 삽입한다면 @Autowired는 무시되는 것인가요?
- 미해결스프링 핵심 원리 - 기본편
전체코드 어디서 볼 수 있나요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.
- 미해결스프링 핵심 원리 - 기본편
main 에서 실행시 finished with non-zero -exit value1 에러 발생
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용] main을 실행 할때마다 아래와 같은 에러가 발생하는데Execution failed for task ':DemoApplication.main()'.> Process 'command 'C:\Program Files\Java\jdk-17\bin\java.exe'' finished with non-zero exit value 1* Try:> Run with --stacktrace option to get the stack trace.> Run with --info or --debug option to get more log output.> Run with --scan to get full insights.> Get more help at https://help.gradle.org.Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.For more on this, please refer to https://docs.gradle.org/8.5/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.BUILD FAILED in 12s3 actionable tasks: 1 executed, 2 up-to-date 아래는 build 설정과 현재 저의 java 버젼입니다.Spring 3.2버전을 사용하고 있습니다. Build and run Using을 바꿀시에는 Intellij IDEA로 바꾸면 되긴하는데 변경하게 되면 rateDiscountPolicy 때문에 여기에서도 에러가 같이 나게 되버립니다. Build and run Using 을 Gradle로 사용해서 실행 시킬 방법은 없나요?
- 미해결스프링 핵심 원리 - 기본편
CoreApplication 오류
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]test 전체 실행을 하였더니 java.lang.IllegalStateException: Failed to load ApplicationContext for [MergedContextConfiguration@4c777e7b testClass = hello.core.CoreApplicationTests, locations = [], classes = [hello.core.CoreApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@5a4ed68f, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@3956b302, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@100f9bbe, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@1a78dacd, org.springframework.boot.test.context.SpringBootTestAnnotation@85e8c2c7], contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null] at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:180) at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130) at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:141) at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:97) at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260) at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:163) at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310) at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735) at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734) at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762) at java.base/java.util.Optional.orElseGet(Optional.java:364) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'memberServiceImpl' defined in file [C:\Users\YWJEONG\study\core\out\production\classes\hello\core\member\MemberServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type 'hello.core.member.MemberRepository' available: expected single matching bean but found 2: memoryMemberRepository,memberRepository at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:802) at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:241) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1354) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1191) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:561) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:960) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:625) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:762) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:464) at org.springframework.boot.SpringApplication.run(SpringApplication.java:334) at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137) at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58) at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46) at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1458) at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:552) at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137) at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:225) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:152) ... 17 moreCaused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'hello.core.member.MemberRepository' available: expected single matching bean but found 2: memoryMemberRepository,memberRepository at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:218) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1420) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353) at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:911) at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:789) ... 41 more이런 오류가 뜹니다 ㅠㅠ
- 미해결스프링 핵심 원리 - 기본편
excludeFilters 가 작동하지않는거같습니다 ㅜㅜ
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (아니오)[질문 내용]안녕하세요 CoreApplication를 실행했는데 오류가 났습니다테스트 돌린 것들은 잘 작동 되었는데 CoreApplication을 실행하면 오류가나요 ㅜㅜ오류내용을 확인하면 AutoAppConfig에서 excludeFilters를 걸어 놓은게 제대로 작동을 안하는거같습니다오류내용은 아래와 같습니다.org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'hello.core.member.MemberRepository' available: expected single matching bean but found 2: memoryMemberRepository,memberRepository @Configuration @ComponentScan( excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class) //예제코드 때문에 필터 설정하였음.. ) public class AutoAppConfig { } 어느 부분이 문제가 있는지 혼자서 못찾겠습니다 도와주세요 ㅜㅜ
- 미해결스프링 핵심 원리 - 기본편
web 라이브러리 추가 후 메인 메서드 실행 에러
request스코프 예제 만들때 web 라이브러리를 아래와 같이 추가 한 뒤, coreApplication Main메서드를 run했을때오류가 떠서 문의 드립니다..!
- 미해결스프링 핵심 원리 - 기본편
DI(의존관계 주입)에 대한 질문입니다!
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]위 코드에서 ac에는 어떤것이 DI되어 입력되는건지 잘 모르겠습니다.ac에 AnnotationConfigAplicationContext가 들어가는게 맞나요?
- 미해결스프링 핵심 원리 - 기본편
AppConfig 에서 각 서비스(MemberServiceImpl, OrderServiceImpl)의 메모리 공간 관련 질문
AppConfig 리팩토링하기 전, new MemoryMemberRepo 를 각각 constructor 파라미터로 넘겨줬습니다. 따라서 MemberServiceImpl 과 OrderServiceImpl 의 메모리 공간이 각각 다를 것으로 생각되는데, 맞나요? 그렇다면 만약 두 서비스가 같은 메모리 공간을 사용하고 싶으면 어떻게 해야되나요?
- 미해결스프링 핵심 원리 - 기본편
스프링 컨테이너와 빈 스코프
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]스프링 컨테이너가 사용되면, 스프링 구성정보(Configuration) 을 활용해서 아래처럼 스프링 빈 저장소에 빈 이름과 빈 객체가 저장된다고 배웠는데요. 싱글톤 컨테이너의 경우에는 AppConfig 파일에서 @Bean으로 수동등록된 것이나, 혹은 컴포넌트 스캔을 통하여 스프링 컨테이너에 객체를 생성하여 등록하는 것으로 알고 있습니다.그런데 프로토타입 스코프와 웹 스코프의 경우에는 스프링 빈 저장소에 빈 객체의 주소값을 저장하는지 궁금합니다.예를 들어, 프로토타입 스코프를 스프링 컨테이너에 조회하면 스프링 컨테이너는 항상 새로운 인스턴스를 생성해서 반환하는데, 그럼 스프링 컨테이너가 생성되는 시점에서 ' 빈 이름 ' 만 등록되고, 빈 객체는 생성되지 않은 채 주소값이 등록되지 않는 것일까요??같은 맥락으로, 웹 스코프에서 request scope은 HTTP 요청이 들어오고 나갈 때까지만 유지되는 스코프입니다.@Component @Scope(value = "request") public class MyLogger {.. }MyLogger 클래스는 위처럼 @Component 로 되어 있기 때문에 컴포넌트 스캔의 대상인데, 그러면 스프링 컨테이너에 등록 될 때 빈 이름만 등록되고 객체는 생성되지 않은 채 등록되는 것일까요?그리고 이후에 @Controller @RequiredArgsConstructorpublic class LogDemoController { private final MyLogger myLogger;... }LogDemoController에서 의존관계 주입으로 MyLogger가 필요할 때, 그 때 비로소 객체가 생성되어서 스프링 컨테이너에 등록되어야 하는데, request scope이기 때문에 오류가 났던 것인가요?? 답변 주시면 감사하겠습니다.
- 미해결스프링 핵심 원리 - 기본편
외부 시스템 연동으로 확장할 때 궁금증
안녕하세요 강의 잘 보고 있습니다. 회원 저장소에 외부 시스템을 연동 하는 것도 인터페이스를 두고 추후에 갈아 끼우면 된다 설명 해주셔서 궁금한 내용이 있습니다.말이 안되는 예시이긴 한 것 같은데 예제가 회원이니 회원으로 예시를 들어보겠습니다.(두 객체를 상황에 따라 동적으로 변경하여 사용하는 예시로 봐주시면 될거같습니다) 예를 들어 DB 회원 저장소로 운영을 하다가, 외부 시스템 연동도 함께 추가해달라는 요구사항입니다.경우에 따라 DB 회원 저장소 또는 외부 시스템에 연동하여 저장합니다. 이때 외부 시스템은 필드명은 물론이고 패스워드 정책 등 검증해야 하는 값이 다르다면 DTO 같은걸 별도로 사용하고 외부 시스템 연동하는 로직에서 검사를 해야 하는 걸까요?아니면 클라이언트에 해당하는 컨트롤러를 분리하고 회원 서비스를 그대로 사용하면 되는걸까요?주저리 주저리 작성한 것 같은데.. 질문의 요지는 외부 시스템 연동으로 확장이 될 때는 다른 필드 다른 검증 등이 필요한데 어떻게 확장하면 좋을지에 대한 질문입니다.긴글 읽어주셔서 감사합니다!
- 미해결스프링 핵심 원리 - 기본편
스프링 빈 모두 조회하기 질문
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.컨테이너에 담긴 모든 빈 조회하기 영상에서 한대로 코드를 따라했는데 코드를 썼을 때 강사님과 달리 자동으로 import되는 것들이 없었고 이에 따라 alt enter을 쓰거나 일일히 타이핑을 통해 import 되는 부분까지 동일히 작성했으나 밑과 같이 AppConfig.class, getBeanDefinitionNames(), getBean()을 인식하지 못하는 것처럼 에러가 뜹니다왜 그런지 모르겠어요
- 미해결스프링 핵심 원리 - 기본편
new AnnotationConfigApplicationContext()
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)예[질문 내용]여기에 질문 내용을 남겨주세요. new AnnotationConfigApplicationContext()에 들어가는 class 정보는 모두 빈으로 등록되는 것 맞나요? 그래서 DiscountService에 @Component와 @Autowired를 사용하지 않아도 테스트가 통과하는 건가요?
- 미해결스프링 핵심 원리 - 기본편
필드 주입 질문있습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)예[질문 내용]필드 주입은 외부에서 변경이 불가능해서 테스트하기 힘들다는 치명적인 단점이 있다고 하셨는데, 외부에서 변경이 불가능하다는게 정확히 무슨 의미인가요? 생성자 주입도 변경이 불가능하지 않나요?
- 미해결스프링 핵심 원리 - 기본편
섹션6. 필터에서 beanA를 찾을 수 없음
@MyIncludeComponent public class BeanA { }@MyExcludeComponent public class BeanB { }package hello.core.scan.filter; import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import static org.assertj.core.api.Assertions.*; import static org.springframework.context.annotation.ComponentScan.*; public class ComponentFilterAppConfigTest { @Test void filterScan() { ApplicationContext ac = new AnnotationConfigApplicationContext(ComponentFilterAppConfig.class); BeanA beanA = ac.getBean("beanA", BeanA.class); assertThat(beanA).isNotNull(); } @Configuration @ComponentScan( includeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyIncludeComponent.class), excludeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyExcludeComponent.class) ) static class ComponentFilterAppConfig { } }강의와 똑같이 따라친 해당 코드에서 org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'beanA' available 에러가 계속 발생합니다. 그래서 아래 코드처럼 BeanA 클래스와 BeanB클래스에 @Component 애노테이션을 추가하였더니 잘 작동합니다. @MyIncludeComponent @Component public class BeanA { } @MyExcludeComponent @Component public class BeanB { } 그런데 이 경우에는 또 하단의 Assertions.thorws 검증 코드가 제대로 작동하지 않습니다. ㅠ .... assertThrows( NoSuchBeanDefinitionException.class, () -> ac.getBean("beanB", BeanB.class)); 그래서 하단 코드처럼 BeanA에만 @Component를 붙이고 BeanB에는 @Component를 붙이지 않으면 테스트 코드가 올바르게 작동합니다... 원인을 알 수 있을까요? @MyIncludeComponent @Component public class BeanA { }@MyExcludeComponent public class BeanB { } BeanA, BeanB, MyExcludeComponent, MyIncludeComponent, ComponentFilterAppConfigTest 모두 테스트의 filter 패키지에 있습니다.
- 해결됨스프링 핵심 원리 - 기본편
@test 자동완성이 안될 때
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]인텔리제이에서 테스트 코드를 작성하기 위해 @Test를 쓸 때, 자동완성이 나오지 않습니다.이렇게만 나오고 @Test에 해당하는 것은 나오지 않습니다. build.gradle에 dependencies도dependencies { implementation 'org.springframework.boot:spring-boot-starter' testImplementation 'org.springframework.boot:spring-boot-starter-test' }위처럼 설정되어 있습니다. 따로 테스트 코드 위에 import org.junit.jupiter.api.Test; 를 작성하면 오류없이 사용 가능하긴한데 자동으로 할 수 있는 방법은 없을까요?Build and run 과 test 모두 Gradle로 설정되어있고 JAVA 17 을 사용하고 있습니다.
- 해결됨스프링 핵심 원리 - 기본편
강의 프로토타입 질문입니다
public class SingletonTest { @Test void singletonBeanFind() { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SingletonBean.class); SingletonBean singletonBean1 = ac.getBean(SingletonBean.class); SingletonBean singletonBean2 = ac.getBean(SingletonBean.class); System.out.println("singletonBean1 = " + singletonBean1); System.out.println("singletonBean2 = " + singletonBean2); Assertions.assertThat(singletonBean1).isSameAs(singletonBean2); ac.close(); } @Scope("singleton") static class SingletonBean { @PostConstruct public void init() { System.out.println("SingletonBean.init"); } @PreDestroy public void destroy() { System.out.println("SingletonBean.destroy"); } } } 영한님이 AnnotationConfigApplicationContext(SingletonBean.class); 여기에 SingletonBean.class를 넣으면 componentscan이 된다고하셨는데 AnnotationConfigApplicationContext는 @Component 혹은 @Bean으로 등록이 되어있는걸 스프링컨테이너로 만들어서 라이프사이클을 관리한다는건데 여기서는 자동으로 빈이나 수동으로 빈을 등록하는게 없는데 어떻게 컴포넌트 스캔으로 관리가되는거죠? 두번째, 컴포넌트스캔이 @SpringBootApplication에 내장되어있어서 자동으로 진행되는건알고있는데 @Test에도 영향을미치나요? 저는 test는 별도로 component를 해줘야하는지 생각했는데 아닌거같아서요
- 미해결스프링 핵심 원리 - 기본편
request scope 관련 질문
질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 내용]request scope 관련해서 실행 과정에서 궁금한게 생겨서 질문드립니다. 제가 이해한 과정이 맞을까요?1. 먼저 CoreApplication을 실행시키면 스프링 컨테이너가 생성이 되고, MyLogger라는 빈을 스프링 컨테이너에 등록시킨다MyLogger라는 빈은 scope이 request 이기때문에http 요청이 오기전까지, 빈 인스턴스를 생성하지 않아서 @PostConstruct가 붙은 초기화 메서드 init()이 실행되지 않는다따라서 uuid를 생성해서 저장하지 못 하기 때문에 "Scope 'request' is not active ... " 와 같은 오류가 발생한다위 과정이 맞다면, 고객의 요청이 오기전까지 Mylogger 빈 인스턴스가 생성되지 않은 상태일텐데 provider가 어떻게 빈을 찾아서 가져오고 @PostContsruct가 실행되는지 궁금합니다. 또한 myLogger.setRequestURL() 메서드가 어느 시점에 실행되는지 궁금합니다.. (빈 생성 전인지 후 인지)그리고 "빈 등록" 과 "빈 생성"은 다른 개념인건가요? 조금 혼동되네요
- 해결됨스프링 핵심 원리 - 기본편
CoreApplication 실행 오류
CoreApplication 실행시 다음과 같은 오류가 발생합니다.
- 해결됨스프링 핵심 원리 - 기본편
강의. 조회된빈이 모두필요할떄 List,map 제목입니다
public class AllBeanTest { @Test void finaAllBean() { 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, 1000, "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<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); return discountPolicy.discount(member, price); } } } 첫번째 질문, AnnotationConfigApplicationContext을 해주게되면 스프링컨테이너로 등록을하고 ac를 통해 빈으로 등록된 AutoAppconfig.class와 DiscountService.class에 접근이 가능하다고 알고있습니다.밑에보면 ac로 DiscountService.class에만 접근하고있어서 AutoAppconfig.class를 빼주었더니 밑에있는 discountprice에 discout에서 오류가 발생합니다. 이유가 무엇일까요? 두번째 질문, 밑에 DiscountService에 강의에서 생성자를 선언해주었습니다. 지금보면 어디에서 호출이되었는지와 어떻게 값을 넣어주었는지 궁금합니다. 제생각에는 AnntationConfigApplicationContext를 할때API문서를 보니 refresh()의 finishBeanFactoryInitialization(beanFactory); 에서 AutoAppConfig.class, DiscountService.class 에 대한 값을 이미 생성되었다고 판단되었는데 이게맞을까요? 이게맞다면 1번질문이 결국 2번질문과 연관되어있을거같습니다 세번째 질문, map에 대해 공부를해봤는데 map<String, DiscountPolicy> 에서 만약 AutoAppconfig 가 들어가있다면 this.policyMap에는 AutoAppconfig가 들어가있는 상태이고 AutoAppconfig를 들여다보니 ComponentScan이 있어서 Component로 등록되어있는 RateDiscountPolicy, FixDiscountPolicy에 매개변수로 들어온 discountCode로 접근이 가능하다가 맞을꺼같은데 제가 이해한게맞을까요?
- 미해결스프링 핵심 원리 - 기본편
빌드하면 나오는 화면 질문
평소 보던 결과랑 다르게 나오는데 저에게 무슨일이 생긴걸까요? 강의랑 같은 결과화면을 얻고싶습니다!이 부분이 강의와 다르게 나타나는 이유가 무엇일까요?