월 24,200원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결스프링 핵심 원리 - 고급편
리플렉션 부분
안녕하세요. 강의 자료 '5.동적 프록시 기술' 의 3쪽에서 참고에 대한 내용으로 람다를 이용해서도 문제 해결을 할 수 있다고 하셨는데, 람다가 익숙하지 않아서 어떻게 하는 건지 궁금합니다..!! 알려주실 수 있을까요??
- 미해결스프링 핵심 원리 - 고급편
자료 오타
영한님, 서포터즈 님들 안녕하세요 :) 코드랑 연관 없어서 정말 별건 아니지만,, 작고 소중한 오타가 하나 있어서 말씀드릴려구요 템플릿 메서드 패턴과 콜백 패턴 복습하는 중에 28페이지에 방법을 없을까 입니다
- 미해결스프링 핵심 원리 - 고급편
AnnotationAwareAspectJAutoProxyCreator 적용 오류
package InflearnSpringCoreAdvanced.CoreProxy.proxy.config.v5_autoproxy;import InflearnSpringCoreAdvanced.CoreProxy.proxy.config.AppV1Config;import InflearnSpringCoreAdvanced.CoreProxy.proxy.config.AppV2Config;import InflearnSpringCoreAdvanced.CoreProxy.proxy.config.v3_proxyfactory.advice.LogTraceAdvice;import InflearnSpringCoreAdvanced.CoreProxy.proxy.trace.logtrace.LogTrace;import org.springframework.aop.Advisor;import org.springframework.aop.support.DefaultPointcutAdvisor;import org.springframework.aop.support.NameMatchMethodPointcut;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;@Configuration@Import({AppV1Config.class, AppV2Config.class})public class AutoProxyConfig { @Bean public Advisor advisor1(LogTrace logTrace) { // Pointcut NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut(); pointcut.setMappedNames("request*", "order*", "save*"); // Advice LogTraceAdvice advice = new LogTraceAdvice(logTrace); // Advisor return new DefaultPointcutAdvisor(pointcut, advice); }} package InflearnSpringCoreAdvanced.CoreProxy;import InflearnSpringCoreAdvanced.CoreProxy.proxy.config.v5_autoproxy.AutoProxyConfig;import InflearnSpringCoreAdvanced.CoreProxy.proxy.trace.logtrace.LogTrace;import InflearnSpringCoreAdvanced.CoreProxy.proxy.trace.logtrace.ThreadLocalLogTrace;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Import;//@Import({AppV1Config.class, AppV2Config.class})//@Import(InterfaceProxyConfig.class)//@Import(ConcreteProxyConfig.class)//@Import(DynamicProxyBasicConfig.class)//@Import(DynamicProxyFilterConfig.class)//@Import(ProxyFactoryConfigV1.class)//@Import(ProxyFactoryConfigV2.class)//@Import(BeanPostProcessorConfig.class)@Import(AutoProxyConfig.class)@SpringBootApplication(scanBasePackages = "InflearnSpringCoreAdvanced.CoreProxy.proxy.app")public class CoreProxyApplication { public static void main(String[] args) { SpringApplication.run(CoreProxyApplication.class, args); } @Bean public LogTrace logTrace() { return new ThreadLocalLogTrace(); }} 현재 AutoProxyConfig, main의 코드는 위와 같고 이를 실행하면 다음과 같은 오류가 발생합니다 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderControllerV1' defined in InflearnSpringCoreAdvanced.CoreProxy.proxy.config.AppV1Config: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [InflearnSpringCoreAdvanced.CoreProxy.proxy.app.v1.OrderControllerV1]: Factory method 'orderControllerV1' threw exception; nested exception is java.lang.NullPointerException: Cannot invoke "InflearnSpringCoreAdvanced.CoreProxy.proxy.trace.TraceStatus.getTraceId()" because "status" is null at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658) ~[spring-beans-5.3.22.jar:5.3.22] at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:486) ~[spring-beans-5.3.22.jar:5.3.22] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) ~[spring-beans-5.3.22.jar:5.3.22] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) ~[spring-beans-5.3.22.jar:5.3.22] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.22.jar:5.3.22] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.22.jar:5.3.22] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.22.jar:5.3.22] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.22.jar:5.3.22] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.22.jar:5.3.22] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.22.jar:5.3.22] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955) ~[spring-beans-5.3.22.jar:5.3.22] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.22.jar:5.3.22] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.22.jar:5.3.22] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.3.jar:2.7.3] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[spring-boot-2.7.3.jar:2.7.3] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.3.jar:2.7.3] at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.7.3.jar:2.7.3] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-2.7.3.jar:2.7.3] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[spring-boot-2.7.3.jar:2.7.3] at InflearnSpringCoreAdvanced.CoreProxy.CoreProxyApplication.main(CoreProxyApplication.java:24) ~[classes/:na] Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [InflearnSpringCoreAdvanced.CoreProxy.proxy.app.v1.OrderControllerV1]: Factory method 'orderControllerV1' threw exception; nested exception is java.lang.NullPointerException: Cannot invoke "InflearnSpringCoreAdvanced.CoreProxy.proxy.trace.TraceStatus.getTraceId()" because "status" is null at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.3.22.jar:5.3.22] at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-5.3.22.jar:5.3.22] ... 19 common frames omitted Caused by: java.lang.NullPointerException: Cannot invoke "InflearnSpringCoreAdvanced.CoreProxy.proxy.trace.TraceStatus.getTraceId()" because "status" is null at InflearnSpringCoreAdvanced.CoreProxy.proxy.trace.logtrace.ThreadLocalLogTrace.response(ThreadLocalLogTrace.java:45) ~[classes/:na] at InflearnSpringCoreAdvanced.CoreProxy.proxy.trace.logtrace.ThreadLocalLogTrace.exception(ThreadLocalLogTrace.java:41) ~[classes/:na] at InflearnSpringCoreAdvanced.CoreProxy.proxy.config.v3_proxyfactory.advice.LogTraceAdvice.invoke(LogTraceAdvice.java:33) ~[classes/:na] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.22.jar:5.3.22] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763) ~[spring-aop-5.3.22.jar:5.3.22] at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708) ~[spring-aop-5.3.22.jar:5.3.22] at InflearnSpringCoreAdvanced.CoreProxy.proxy.config.AppV1Config$$EnhancerBySpringCGLIB$$f7cc6e87.orderControllerV1(<generated>) ~[classes/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na] at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.3.22.jar:5.3.22] ... 20 common frames omitted 결국 ThreadLocalLogTrace에서 response에서의 TraceStatus가 null값이 들어가서 생긴 NPE 오류라고 나오는데 이전에 AnnotationAwareAspectJAutoProxyCreator가 아닌 직접 빈 후처리기를 만들고 등록할때까지는 아무런 오류가 없었는데 AnnotationAwareAspectJAutoProxyCreator를 등록하고 난 후에 main자체가 띄워지지가 않는데 어디가 문제인가요?? build.gradle에는 aop적용하였고 버전을 낮춰봤는데도 버전문제가 아닌거 같습니다
- 미해결스프링 핵심 원리 - 고급편
템플릿메서드 포함 실제 개발 할 때 적용 위치
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 안녕하세요 영한님 강의 전부 수강하고 있는 수강생 입니다. 실제로 개발 할 때는 보통 디렉토리 구조가 controller / service / repository / domain 으로 나누어져 있는데 실제 저런 패턴을 적용 해야 하는 위치 는 대두분 서비스단으로 생각이 됩니다. 그럼 하나의 서비스 클래스 파일에서 중복을 피하려고 템플릿메서드 패턴을 적용 할 때 추상클래스와 그 하위 오버라이딩 된 클래스들의 파일 위치를 해당 패턴을 사용하 는 서비스와 같은 위치에 둬야 할까요? 아니면 따로 디렉토리를 생성해서 모든 서비스의 패턴적용을 위한 클래스 들을 모아둬야 할까요? 사실상 어디에 둬도 실제 개발엔 문제가 없고 정답이 없는 얘 기라고 생각되나 영한님의 개인적인 견해가 궁금해서 여쭤봅 니다!
- 미해결스프링 핵심 원리 - 고급편
`..` 다음에 *.*을 하는 이유
안녕하세요. 코드를 따라치다가 한 가지 궁금한 점이 있습니다. 이전에 배우기로는 `..`는 하위 패키지를 포함하는 걸로 알고 있습니다. @Before("execution(* hello.aop.internalcall..*.*(..))") 위 코드 대신에 @Before("execution(* hello.aop.internalcall..*(..))") 이렇게만 만해도 충분하지 않나요? 1번처럼 작성하신 이유가 궁금합니다.
- 해결됨스프링 핵심 원리 - 고급편
advisor 메서드 단위에서 순서 지정
안녕하세요. 이전 강의에서는 advisor를 수동으로 지정해줄 경우 어떤 메서드를 먼저 작성해주느냐에 따라 advisor 순서를 지정해준 거 같은데요, @Aspect를 사용해서 advisor를 지정해줄 경우 메서드 단위에서는 advisor 순서를 정해주지 못하나요??
- 미해결스프링 핵심 원리 - 고급편
로그 검증과 관련되어 질문드립니다.
안녕하세요! 강의를 듣다가 로그 검증이 하고 싶어 진행하다 궁금증이 생겨 질문글을 올렸습니다.☺️ 1. 생성한로그를 테스트하기 위해서 ListAppender에 로그들을 담아서 테스트를 진행하게 됐는데, 해당 방식으로 테스트를 진행하는 방법말고도 다른 방법도 있나요? 2. 실제 비즈니스 로직에서 해당 로그 출력 검증을 단위 테스트할 때 진행하게 되나요? 3. 실무에서는 로그를 검증하기 위해 어떤 방식을 사용하는지 궁금합니다.
- 해결됨스프링 핵심 원리 - 고급편
@Import(AppV1Config.class) 질문있습니다.
안녕하세요. 강사님!한가지 궁금한 사항이 있어서 질문드립니다. 강의에서 필요한 컴포넌트만 스캔하기 위해서 hello.proxy.app 하위만 scanBasePackages로 설정해주셨는데 별개로 AppV1Config 클래스를 bean 으로 등록하기 위해서 ProxyApplication 클래스위에 @Import(AppV1Config.class)를 선언하셨었는데, 어떻게 AppV1Config 클래스가 독립적으로 빈으로 등록되는지 상세하게 알수있을까요? 공식 doc을 봐도 이해가 안되네요 ㅠㅠ AppV1Config 클래스에 적용된 @Configuration 어노테이션을 까보니 @Component 어노테이션이 적용되었지만, 애플리케이션 기동시에는 @SpringBootAppilcation 어노테이션의 scanBasePackages를 hello.porxy.app 하위로 적용했기 때문에 hello.proxy.config 하위에 있는 AppV1Config가 무시되지는 않나 싶어서요 공홈을 보니까 There's no problem in declaring all the configurations. But imagine the trouble to control dozens of configuration classes within different sources. There should be a better way. The @Import annotation has a solution, by its capability to group Configuration classes:이렇게 설명이 되어있는데 혹시 hello.proxy.app 하위로 컴포넌트 스캔을 할 경우 @Import에 있는 Configuration으로 등록되어 있는 AppV1Config 파일도 함께 grouping 되어서 스캔되는 원리일까요?
- 미해결스프링 핵심 원리 - 고급편
컨트롤러 프록시가 어떻게 호출되는지 잘 모르겠습니다
인터페이스에 GetMapping이 되어있고 이 인터페이스를 Impl 구현체와 프록시가 각각 구현하고 있는데 어떤 이유로 Impl이 아닌 프록시가 호출되는지 잘 모르겠습니다. 마찬가지로 구체클레스에 적용하는 V2도 OrderController가 아닌 이것을 상속받은 프록시가 호출되는 이유가 궁금합니다
- 미해결스프링 핵심 원리 - 고급편
로드맵
스프링 기본에서 db2편까지 다들으면 바로 jpa로드맵 강의 들어도 되나요? 토이프로젝트를 하고싶은데 고급편은 언제쯤 들어야 할지 고민되네요...
- 미해결스프링 핵심 원리 - 고급편
@Around 오류
@Around에서 리턴값을 바꾸면 ClassCastException이 발생합니다. Controller에 aop를 적용해서 target controller는 String을 반환하게 했고 advice에서는 ResponseEntity를 반환하게 설정했는데요... 다음과 같은 오류가 발생합니다.. 디버깅을 찍어봐도 이유를 모르겠습니다. 원인이 무엇인지 알려주시면 감사하겠습니다!!! org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.ClassCastException: class org.springframework.http.ResponseEntity cannot be cast to class java.lang.String (org.springframework.http.ResponseEntity is in unnamed module of loader 'app'; java.lang.String is in module java.base of loader 'bootstrap') at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:72) at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167) at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134) at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:199) at com.github.rere950303.apiutil.aspect.ResponseApiAspectTest.methodName(ResponseApiAspectTest.java:71) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725) at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84) at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115) at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.base/java.util.ArrayList.forEach(ArrayList.java:1541) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.base/java.util.ArrayList.forEach(ArrayList.java:1541) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53) at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71) at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38) at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)Caused by: java.lang.ClassCastException: class org.springframework.http.ResponseEntity cannot be cast to class java.lang.String (org.springframework.http.ResponseEntity is in unnamed module of loader 'app'; java.lang.String is in module java.base of loader 'bootstrap') at com.github.rere950303.apiutil.aspect.ResponseApiAspectTest$TestController$$EnhancerBySpringCGLIB$$8953dbd8.test2(<generated>) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ... 78 more
- 미해결스프링 핵심 원리 - 고급편
추상클래스의 메서드를 포인트컷으로 잡을 수 없나요?
안녕하세요. AOP 포인트컷 관련 테스트를하다가 제가 잘 모르는 부분이 있어서 질문을 드립니다. 인터페이스에서 구체클래스의 내부메서드를 포인트컷으로 잡지 못하는것은 이해가 잘되는데요. 구체클래스(자식클래스)에서 부모클래스를 잡을 수 있을것이라고 생각했는데테스트해보니, 제 의도와 다른결과가 나오더라고요. 프록시는 프록시 클래스의 메서드(직접 정의했거나 Override)만 대상이 되나요? 어떤부분,키워드로 이해를 위한, 부족한 지식을 보완할 수 수 있을까요..?강의에 언급되었는데 제가 놓쳤다면, 그 부분을 알려주시면 다시 보도록 하겠습니다. 감사합니다. --- 샘플코드: https://github.com/seolys/spring-aop-pointcut-oop- 테스트코드로 작성하였습니다: 테스트코드 경로
- 미해결스프링 핵심 원리 - 고급편
수업 내용중에 2분 40초쯤(템플릿메서드패턴 예제 1)
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. logic1() 과 logic2()의 로직이 거의 비슷한데 시간은 계속해서 다른 것으로 보입니다. 혹시 원인을 알 수 있을까요?
- 미해결스프링 핵심 원리 - 고급편
test 메서드 snake case
영한님 안녕하세요. 테스트 케이스 작성하실 때, 메서드 이름을 camel 케이스가 아니라 snake case로 작성하시던데, db 강의 때도 그렇게 하셔서 궁금했는데 뭔가 이유가 있으신 건가요?
- 미해결스프링 핵심 원리 - 고급편
프록시로 감싼 빈에 대한 재사용성 질문
안녕하세요 ! 스프링 컨테이너에서 빈을 가져와 프록시 기능이 필요할 경우 프록시로 래핑을 해주는걸로 아는데 이 때 프록시 객체로 래핑한 결과물은 1회성으로 사용하고 버리나요? 아니면 그 또한 재사용을 위해 어딘가에 캐싱을 해두나요?
- 미해결스프링 핵심 원리 - 고급편
JoinPoint.getThis() 반환값
JoinPoint.getThis() 반환값을 출력해보니 Target 객체가 나오는 것 같습니다.. JoinPoint.getTarget() 과 동일한 값이 나옵니다. getThis() 하면 proxy 객체가 나와야 될 것 같은데, (예제에서는 interface 가 없는 구현체이므로, CGLIB 객체) Target 객체가 나오는 이유가 있을 까요? @Before("hello.aop.order.aop.Pointcuts.orderAndService()")public void doBefore(JoinPoint joinPoint) { log.info("[before] {}", joinPoint.getSignature()); log.info("[before this] {}", joinPoint.getThis()); log.info("[before target] {}", joinPoint.getTarget());} 2022-06-28 22:04:55.928 INFO 1765 --- [ Test worker] hello.aop.order.aop.AspectV6Advice : [before this] hello.aop.order.OrderService@f171912 2022-06-28 22:04:55.929 INFO 1765 --- [ Test worker] hello.aop.order.aop.AspectV6Advice : [before target] hello.aop.order.OrderService@f171912 감사합니다.
- 해결됨스프링 핵심 원리 - 고급편
target 인스턴스도 빈으로 등록은 되는 건가요?
강의를 재밌게 보고 있는데, 의문이 있어서 질문드립니다. "대안1 자기 자신 주입" 강의 0:47 때 그림을 보여주시는데, 해당 그림에서는 target 인스턴스 내에서 proxy 를 의존성 주입 받아서 사용하는 걸로 표현됩니다. 여기서 의문이 들었습니다. 제 지식으로는 "스프링 빈으로 proxy 가 등록되고, target 은 빈으로 등록되지 않고, proxy 가 내부에서 참조만 한다"라고 알고 있습니다.(틀리다면 꼭 지적해주십쇼!) 그리고 또 한가지는 제가 알기로는 "의존성 주입을 위해서는 쓰는 쪽과, 받는 쪽 모두 빈으로 등록되어 있어야 한다."라는 것입니다. 이 두 가지 생각을 합치니 0:47 에 나오는 그림이 이상해 보였습니다. 그림 상에서는 빈으로 등록되지 않은 target 인스턴스가 의존성 주입을 받고 있는 걸로 보이거든요... 그림 처럼 되려면 target 인스턴스도 빈으로 등록이 되어야 하는데... 혹시 target 인스턴스도 빈으로 등록이 된건가요??
- 미해결스프링 핵심 원리 - 고급편
Advisor의 빈 저장소 등록 시점이 빈 처러기의 대상이 될 객체의 빈 저장소 등록 시점 보다 어떻게 더 빠를 수 있나요?
1. 생성: 스프링이 스프링 빈 대상이 되는 객체를 생성한다. ( @Bean , 컴포넌트 스캔 모두 포함)2. 전달: 생성된 객체를 빈 저장소에 등록하기 직전에 빈 후처리기에 전달한다.3. 모든 Advisor 빈 조회: 자동 프록시 생성기 - 빈 후처리기는 스프링 컨테이너에서 모든 Advisor 를 조회한다.4. 프록시 적용 대상 체크: 앞서 조회한 Advisor 에 포함되어 있는 포인트컷을 사용해서 해당 객체가 프록시를 적용할 대상인지 아닌지 판단한다. 이때 객체의 클래스 정보는 물론이고, 해당 객체의 모든 메서드를 포인트컷에 하나하나 모두 매칭해본다. 그래서 조건이 하나라도 만족하면 프록시 적용 대상이 된다. 예를 들어서 10개의 메서드 중에 하나만 포인트컷 조건에 만족해도 프록시 적용 대상이 된다. 제가 이해한 바로는 3.에서 스프링 컨테이너에 Advisor들은 이미 스프링 컨테이너에 등록 되어있는 것을 찾아오고 빈 후처리기에서 Advisor를 적용하여 프록시 객체를 생성할 target객체들은 생성만 되어있고 스프링 컨테이너에는 등록이 안되어 있는 것으로 이해했습니다. 이렇게 되려면 스프링이 Advisor를 구분해서 먼저 스프링 컨테이너에 등록 할 수 있어야 할 것 같은데 제가 제대로 생각하고 있는 것이 맞을까요?
- 해결됨스프링 핵심 원리 - 고급편
로그 추적기를 프로젝트에 적용하기 위해서..
안녕하세요. 로그추적기를 적용할 때 try/catch를 사용하던데 이렇게 되면 모든 컨트롤러, 서비스, 매퍼, 레포지토리에서 항상 try/catch를 사용해야 하는 건가요? 제가 듣기로는 컨트롤러는 try/catch를 가능하면 지양하라고 들었는데.. 어떻게 하는 게 좋은 걸까요?
- 해결됨스프링 핵심 원리 - 고급편
Junit Test 에서 setDaemon(true) 를 안했어도 테스트 코드가 종료되는 이유가 뭘까요?
안녕하세요. "동시성 문제-예제코드" 강의 07:35 쯤에 나오는 설명과 실행결과가 이해가 안되서 질문드립니다. 제가 알기로는 메인 쓰레드가 종료가 되더라도, Thread thread = new Thread(); thread.setDaemon(true); 처럼 하지 않으면 프로그램이 끝나지 않는 걸로 알고 있습니다. 그런데 Junit Test 내에서는 thread.setDaemon(true)를 안 했음에도 그냥 테스트 코드가 종료되버립니다. 대체 이렇게 동작하는 원인이 뭘까요?