월 24,200원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결스프링 핵심 원리 - 고급편
선생님 작성한 정적 팩토리 메서드에 대해 의견 주실 수 있으실까요??
안녕하세요! 프로젝트와 관련해 코드를 작성하다 궁금한 점이 생겨 질문 드립니다..! 혹 선생님께서는 정적 팩토리 메소드의 역할이 어디까지라고 생각하실까요? 저는 팩토리 메소드이기 때문에 1. 단순히 파라미터를 받아 생성자를 통해 인스턴스를 생성하는 것 뿐만 아니라, 인스턴스를 생성하기 위해 2. 파라미터 valiation을 확인하고, 인스턴스 생성을 위한 데이터들을 가공하는 과정 또한 포함해도 괜찮은 것이 아닌가 하였는데,저와 다른 의견 중에서는 팩토리 메소드는 가공이 전부 완료된 값을 단순히 받아서 인스턴스를 new 하기만 해야 한다는 의견이 있더라구요. 가공은 서비스 클래스에서 수행하구요! 예를 들면 아래와 같은 메소드가 validation과 데이터 가공을 처리하는 팩토리 메소드의 예시입니다 ::public static SearchRequest from( AnotherRequest request) { 55 //AnotherRequest 클래스로부터 SearchRequest 클래스를 생성함. if(request.get고객리스트().size() > 9) { 56 //validation? 혹은 비즈니스 로직? throw new Exception(); 57 } 58 //아래부터 데이터 가공 List<Passenger> 새로운 고객리스트 = request.get고객리스트().stream() 59 .map(p -> new Passenger(p.get생일(), p.get성별()) ) 60 .collect(Collectors.toList()); 61 62 //인스턴스 생성 후 return return new SearchRequest(새로운 고객리스트); 63 } 또한 webClient를 이용해 외부로 API 요청을 보내고자 할 때, path 값을 관리하는 과정에서,해당 path 값 ( ex. /a/b/xxx ) 을 반드시 webClient를 변수로 주입받아 실제 통신을 하는 class에서 가지고 있는 것과 혹은 통신 시 사용되는 request 데이터 dto 에서 그 변수 값을 가지고, 실제 통신을 하는 class에서는 request dto에서 getPath()를 통해 가져와 사용하는 것 어느 부분이 더 적절하다고 생각하실까요?저는 2번의 경우 webClient를 사용하는 클래스에서 추가적으로 여러 개의 path에 대한 상수 변수를 가지고 있을 필요가 없고 getPath()라는 메소드를 통해서 request dto의 종류를 신경쓰지 않고 일관되게 가져올 수 있다는 점에서 2번이 더 괜찮다고 생각을 하였는데, 다른 의견에서는 패스 값은 통신에 사용되는 값이기 때문에 dto가 아닌 통신을 하는 클래스가 가져야 하는게 더 자연스럽다. 그래서 새 기능이 추가되었을 때 통신을 하는 클래스 ( webClient를 변수로 가진 ) 에 패스에 대한 상수변수를 추가하고 패스에 따른 통신 메서드를 추가하는 것이 더 낫다. 라는 의견이 있었습니다. 코드 스타일에 따라 정답은 없겠지만, OOP의 입장에서 선생님의 의견을 여쭙고자 합니다! 답변 해주시면 정말 감사하겠습니다!
- 미해결스프링 핵심 원리 - 고급편
어드바이스 추가 질문드립니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]어드바이스가 하나 더 추가돼서 Service에선 log 관련 프록시랑 트랜젝션 관련 프록시가 두개가 생기면joinPoint.proceed(); 메서드가 두번 호출되어'[orderService] 실행' 메세지가 두번 찍혀야되는거 아닌가요?두 어드바이스가 체인 형식으로 묶이는 건가요?
- 미해결스프링 핵심 원리 - 고급편
LogTraceAspect nolog
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용] package hello.proxy.config.v6_aop.aspect; import hello.proxy.trace.TraceStatus; import hello.proxy.trace.logtrace.LogTrace; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import java.lang.reflect.Method; @Slf4j @Aspect public class LogTraceAspect { private final LogTrace logTrace; public LogTraceAspect(LogTrace logTrace) { this.logTrace = logTrace; } @Around("execution(* hello.proxy.app..*(..))") public Object execute(ProceedingJoinPoint joinPoint) throws Throwable { TraceStatus status = null; try { String message = joinPoint.getSignature().toShortString(); status = logTrace.begin(message); //로직 호출 Object result = joinPoint.proceed(); logTrace.end(status); return result; } catch (Exception e) { logTrace.exception(status, e); throw e; } } }nolog 요청에는 로그를 안남기기 위해서 포인트컷을 수정해야되는거 아닌가요???
- 미해결스프링 핵심 원리 - 고급편
proxy프로젝트가 임포트되질않습니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예[질문 내용]proxy-start 프로젝트를 다운받고 폴더이름 proxy로 변경후강의에서 말씀하신 데로 open as project로 프로젝트를 실행했는데 "Connection refused: no further information"에러가 뜨면서 프로젝트가 임포트되질않습니다. 사진에서 처럼 프로젝트쪽에 아예 모듈이 임포트가 안됩니다. 강의에서 제공하는 압축파일에서 전혀 손대지 않고 그대로 사용하엿습니다.자주 하는 질문에 스프링3버전이상 jdk17버전 이상 사용은해당문제와는 관련이 없어보이긴 했지만 (advanced프로젝트는 문제 없이 작동하였음)스프링버전3이상 자바17로 세팅해도 여전히 같은현상이 반복됩니다 확인부탁드립니다.
- 미해결스프링 핵심 원리 - 고급편
템플릿 메소드 패턴과 전략 패턴
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]강의에서 템플릿 메소드의 경우에는 부모 클래스가 바뀌면 자식 클래스에 영향을 미치는 반면에, 전략 패턴의 경우엔 Context 코드가 변경되더라고 Strategy부분에 영향을 미치지 않는다고 설명하셨는데,,, 이 부분이 정학히 이해가 되지않습니다. 혹시 간단한 예시를 통해 이 둘의 차이를 알 수 있을까요ㅠ?
- 미해결스프링 핵심 원리 - 고급편
interfaceProxy에 대해서 질문 있어요
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]인터페이스 프록시들이 잘 살펴보면 조금씩은 차이가 있지만 비슷한데 이것들을 전략패턴이나 아니면 다른 방식으로 또 통합 가능한가요?
- 미해결스프링 핵심 원리 - 고급편
인터페이스 객체지향에 대해..
김영한님 강의를 듣다보면 객체지향다형성, 인터페이스프로시 이런얘기를 많이들었습니다만ㅠㅠ이해가 안되는거 하나 여쭙고싶네요..보통 스프링 프로젝트 보면컨트롤러에 서비스 인터페이스 선언해두고이를 다시 서비스임플로 구현하자나요이걸 도대체 왜 하는걸까요?ㅠㅠ제 생각엔 인터페이스 둔다는것 자체가구현체를 필요에 따라 갈아끼우겠다는건데..보통 컨트롤러에 선언해둔 서비스 인터페이스의 의도를 알고싶습니다.,../ㅠㅠㅠ
- 미해결스프링 핵심 원리 - 고급편
포인트컷 지시자와 매개변수 전달
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 네2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 네3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 네[질문 내용]매개변수 관련된 부분 학습 중에 헷갈리는 내용이 있어서 질문 드립니다.예를 들어 @annotation은 특정 어노테이션 기반으로 aop 프록시 대상을 정하는 것으로 배웠고, 다음과 같이 사용했습니다. @Around("@annotation(hello.aop.member.annotation.MethodAop)") public Object doAtAnnotation(ProceedingJoinPoint joinPoint) throws Throwable { log.info("[@annotation] {}", joinPoint.getSignature()); return joinPoint.proceed(); }그런데 매개변수 전달에서 @annotation은 특정 annotation을 전달하는 것으로도 보이는데요, @Before("allMember() && @annotation(annotation)") public void atAnnotation(JoinPoint joinPoint, MethodAop annotation) { log.info("[@annotation]{}, annotationValue={}", joinPoint.getSignature(), annotation.value()); }그렇다면 두 번째 경우에, aop 프록시 대상에 @MethodAop를 갖고 있는 대상에 대해서 적용이 되는 걸까요? 해당 어노테이션만 전달하는 건지, 해당 어노테이션을 갖고 있는 경우에 적용하는 기능까지 포함된 건지 (이 경우엔 생략된걸까요?) 궁금합니다
- 미해결스프링 핵심 원리 - 고급편
포인트컷 지정, 매개변수 전달
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예[질문 내용]안녕하세요 포인트컷 지시자에서 표현식 중 매개변수 전달에 대해서 헷갈리는 부분이 있어서 질문 남깁니다.예를 들어 @annotation 지시자의 경우에는 해당 annotation이 있는 경우에 aop 적용 대상으로 인식하는 것으로 배웠는데요, @Around("@annotation(hello.aop.member.annotation.MethodAop)") public Object doAtAnnotation(ProceedingJoinPoint joinPoint) throws Throwable { log.info("[@annotation] {}", joinPoint.getSignature()); return joinPoint.proceed(); }@annotation을 매개변수 전달로도 사용할 수 있다고 강의에서 배웠습니다.
- 미해결스프링 핵심 원리 - 고급편
Gradle과 Intellij IDEA의 실행 결과 차이가 발생합니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]Intellij IDEA를 실행했을때 whitelabel error가 뜨고 Gradle로 실행했을때는 정상적으로 작동이 되는지 잘 모르겠습니다.<Gradle로 실행했을 때><Intellij IDEA로 실행했을 때>2024-04-24T10:14:45.934+09:00 ERROR 11612 --- [advanced] [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.IllegalArgumentException: Name for argument of type [java.lang.String] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag.] with root causejava.lang.IllegalArgumentException: Name for argument of type [java.lang.String] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag. at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.updateNamedValueInfo(AbstractNamedValueMethodArgumentResolver.java:187) ~[spring-web-6.1.6.jar:6.1.6] at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.getNamedValueInfo(AbstractNamedValueMethodArgumentResolver.java:162) ~[spring-web-6.1.6.jar:6.1.6] at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:108) ~[spring-web-6.1.6.jar:6.1.6] at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:122) ~[spring-web-6.1.6.jar:6.1.6] at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:224) ~[spring-web-6.1.6.jar:6.1.6] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:178) ~[spring-web-6.1.6.jar:6.1.6] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.1.6.jar:6.1.6] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926) ~[spring-webmvc-6.1.6.jar:6.1.6] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831) ~[spring-webmvc-6.1.6.jar:6.1.6] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.1.6.jar:6.1.6] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.1.6.jar:6.1.6] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.1.6.jar:6.1.6] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.1.6.jar:6.1.6] at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) ~[spring-webmvc-6.1.6.jar:6.1.6] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) ~[tomcat-embed-core-10.1.20.jar:6.0] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.1.6.jar:6.1.6] at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.20.jar:6.0] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.20.jar:10.1.20] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.1.6.jar:6.1.6] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.6.jar:6.1.6] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.1.6.jar:6.1.6] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.6.jar:6.1.6] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.1.6.jar:6.1.6] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.6.jar:6.1.6] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.20.jar:10.1.20] at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na] Chat GPT로 물어봤는데 이해가 되지 않아서 질문 남깁니다. 두 방식으로 돌렸을 때 왜 이런 차이가 발생하는 건가요??
- 미해결스프링 핵심 원리 - 고급편
어노테이션 내부에 가지는 값을 표기할 때 ()를 사용하는 이유
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]강의 감사하게 잘 수강하고 있습니다!어노테이션 내부에 가지는 값을 표기할 때 다음과 같이int value();선언을 하는데, 어노테이션 내부에 선언할 때int value이렇게 하지 않고 꼭 뒤에 소괄호를 붙여야 하는 이유가 있을까요? 어노테이션 내부에 가지는 값을 선언할 때 지켜야되는 당연한 규칙이라고 알고있는데, 왜 이런 규칙이 있는지 내부 동작원리랑 함께 알고싶습니다!
- 미해결스프링 핵심 원리 - 고급편
프록시가 있어야 어드바이스를 적용할 지 말지를 판단한다는게 무엇인지 잘 모르겠습니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]강의 내용을 다시 읊어보면," 이번 예제를 보면 execution(* hello.aop..*(..)) 를 통해 적용 대상을 줄여준 것을 확인할 수 있다. args , @args , @target 은 실제 객체 인스턴스가 생성되고 실행될 때 어드바이스 적용 여부를 확인할 수 있다." 여기까지는 이해했습니다.다음 부분부터 이해가 잘 안되는데,==" 실행 시점에 일어나는 포인트컷 적용 여부도 결국 프록시가 있어야 실행 시점에 판단할 수 있다. " 여기서 실행이라는 것이 애플리케이션의 실행을 말씀하시는 것인가요? 아니면 프록시로 생성된 인스턴스의 메소드 실행을 의미하는 것인가요? == =="프록시가 없다면 판단 자체가 불가능하다. 그런데 스프링 컨테이너가 프록시를 생성하는 시점은 스프링 컨테이너가 만들어지는 애플리케이션 로딩 시점에 적용할 수 있다. " 이 부분도 잘 이해가 가지 않습니다. 스프링 컨테이너가 프록시를 생성하는 시점을 애플리케이션 로딩 시점에 적용할 수 있다는 것이 어떤 의미인가요? 스프링 컨테이너가 프록시를 생성하는 시점과, 애플리케이션 로딩 시점이 같다는 의미일까요? ==== " 따라서 args , @args , @target 같은 포인트컷 지시자가 있으면 스프링은 모든 스프링 빈에 AOP를 적용하려고 시도한다. " 예를들어 @target같은 경우는, 주어진 어노테이션이 붙어있는 클래스의 인스턴스가 스프링 빈으로 등록이 되려고 할 때에만 AOP를 적용하려고 시도하는 것이 아닌가요?
- 미해결스프링 핵심 원리 - 고급편
@Retention(RetentionPolicy.RUNTIME) 질문입니다!
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]@Retention(RetentionPolicy.RUNTIME)을 붙이게 되면 해당 어노테이션이 애플리케이션 실행될 때 까지 살아있다는 것이 정확히 어떤 의미인지 알고 싶습니다!
- 미해결스프링 핵심 원리 - 고급편
JDK 동적 프록시 질문입니다.
JDK 동적 프록시 - 예제 코드해당 강의 수강 중 궁금한 게 있어 질문드립니다.해당 코드에서method.invoke(target, args); 메서드를 사용하여target의 인터페이스 메서드를 실행하게 되는데 target의 인터페이스에 메서드가 여러 개 존재할 시 어떤 메서드를 호출할지는 어떻게 결정하게 되나요?
- 미해결스프링 핵심 원리 - 고급편
ApplicationContext생성을 명시적으로 하지 않으면
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]지금까지 대부분의 테스트에서는 new ApplicationConfigApplicationContext(Config객체) 를 명시하지 않았는데,이렇게 명시하지 않아도 정상적으로 스프링 컨테이너가 생성이 되고 거기다가 빈 등록도 잘 되는걸로 알고 있습니다!.명시하지 않으면 자동으로 위와 같은 코드를 생성해주는 것인가요?>
- 미해결스프링 핵심 원리 - 고급편
런타임 시점의 정확한 의미는?2개?한개?
1. CGLIB에서 말하는 런타임의 정확한 시점이 궁금한데? 프록시를 생성하고 바이트 코드를 조작하는 그 시점이 런타임 이다 라고 하는게 맞나요? 스프링이 빈을 컨테이너에 등록하기 이전에 프록시를 생성해서 빈으로 등록하는 그 시점을 런타임이라고 하는거죠?2. AOP 적용 방식 3가지 중 마지막 런타임시점에 대해여기서 스프링이 쓰는 AOP도 결국 CGLIB인데 그러면 여기서 말하는 런타임의 정확한 의미도 1번과 동일한 시점을 얘기하는건가요?아니면 실제 객체의 메소드를 호출하는 그 시점을 런타임 이라고 얘기하는건가요? 아니면 둘다인가요?
- 미해결스프링 핵심 원리 - 고급편
위빙
위빙이 AOP 적용을 위해 애스펙트를 객체에 연결한 상태라고 하셨는데객체는 실제 타겟 객체이지요?스프링 AOP 는 런타임시점에, 컨테이너 로딩시점에, 프록시 생성시점에 위빙을 한다라고 하셨는데위빙이란게 결국 아래 코드 부분의 부가기능이 타겟 객체 호출(joinPoint.proceed) 앞뒤로 만들어주는걸(프록시 객체를 생성하는 시점에서 바이트 코드를 조작해서 심어줌)말씀하시는건가요?
- 미해결스프링 핵심 원리 - 고급편
섹션 11 @target, @within 중 질문
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 네2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 네3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 네[질문 내용]여기에 질문 내용을 남겨주세요. 안녕하세요, AOP에서 사용하는 포인트컷 지시자에서, args, @args, @target은 단독으로 사용하게 된다면 스프링 모든 빈에 대해서 적용을 시도하기 때문에, 에러가 나는 것을 강의에서 확인해주셨는데요.그런데, execution을 사용할 때 모든 메서드에 대해서 적용이 가능하도록 execution(* *(..)) 과 같은 식으로 사용해도 스프링 모든 빈에 대해서 적용을 시도하게 되고, 그러면 동일하게 에러가 발생해야되지 않는지 궁금합니다! (test 초반에 에러 안 나는 것은 봤는데 왜일까요 ㅠㅠ)
- 미해결스프링 핵심 원리 - 고급편
CGLIB 와 클래스 로딩시점의 차이..
동적 프록시로 앞에서 배운 CGLIB도바이트 코드를 조작하는거 아닌가요?그런데 CGLIB도 프록시를 사용하는것이자나요? AOP에서 AspectJ의 클래스로딩시점에 바이트 코드을 조작한다는건 무슨차이인가요? 여기서는 프록시를 사용안하고 바이트 코드만 조작한다는거고cglib는 바이트 코드도 조작하고 프록시도 사용하나요..?그런거라면.. 바이트 코드를 어차피 조작할건데 cglib는 왜 프록시를 사용하나요?ㅠㅠ
- 미해결스프링 핵심 원리 - 고급편
concrete proxy controller에는 requestmapping이 없지 않나요?
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]보니까 ControllerV2에는 @Getmapping으로 인해 url매핑이 잘 되어 있는데, 결국 이 controllerv2가 아닌 concrete proxy controller가 스프링 빈으로 등록이 될 것이고, 클라이언트가 url을 입력해 요청하면 이 구체 프록시 컨트롤러로 요청이 갈텐데, 문제는 여기에 @Getmapping이 없어서 요청을 못받지 않나요>? 아니면 이 concrete proxy controller가 controllerv2를 상속받기때문에, controllerv2의 @Getmapping정보까지 같이 가져가게 되는건가요?