월 24,200원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 해결됨스프링 핵심 원리 - 고급편
컨트롤러에 프록시를 적용하는경우
프록시 객체같은 경우에는 RestController 혹은 RequestBody같은 어노테이션을 달수없텐데 어떻게 http request 객체가 프록시 controller객체에 가장먼저 들어가게 되나요?? 프록시가 없을때는 RestController 어노테이션때문에 컨트롤러로 request객체가 가장 먼저 들어온다고 생각했는데 프록시가 생기면 어떤 원리로 프록시 컨트롤러 객체로 request가 들어오는지 궁금합니다
- 미해결스프링 핵심 원리 - 고급편
회원 유효성 검사에 AOP 를 적용해도 될까요?
안녕하세요 강사님 AOP 를 배우니, 개인 프로젝트에 적용하고 싶은 생각이 들어 질문을 드립니다. 현재 게시판 서비스를 개발중입니다. 이 때 탈퇴한 회원의 글이나, 숨김 처리된 글은 화면단에서 보이지 않도록, 게시글 조회 API 마다 "필터 로직"을 중복하여 사용하고 있습니다. 그렇다 보니, api 마다 중복되는 필터 로직을 AOP 로 대체할 수 있지 않을까 생각이 들었습니다. 학습 자료를 보니 "오류 검사 및 처리, 동기화, 성능 최적화, 모니터링/로깅" 에 AOP 가 사용된다고 적혀있는데, 제가 구현하고자하는 필터링 로직도 AOP 를 적용하는 것이 적절한지 궁금하여 질문 드립니다 감사합니다 ! 회원의 유효성 검사라는 횡단 관심사의 문제는 충족하지만, 이를 DB 단이 아닌 AOP 를 적용하여 해결하는 것이 적절한 방법인지에 대한 궁금증이라 생각해주시면 감사하겠습니다 :))
- 미해결스프링 핵심 원리 - 고급편
실행시간에 따른 log 레벨 적용
강사님께서 말씀주신 실행시간에 따른 log 레벨 적용해 보았습니다. 필요하신 부분 참고부탁 드립니다. (오류시에만 로그 남기는 부분은 @AfterThrowing을 사용하면 될것같습니다, - retry 에서 재시도 부분 제거) 1. 애노테이션 - 기본값 1000 @Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface CheckTime { int value() default 1000;} 2. Aspect @Around("@annotation(checkTime)")public void checkTimer(ProceedingJoinPoint joinPoint, CheckTime checkTime) throws Throwable { int mills = checkTime.value(); int maxMills = 4000; StopWatch stopWatch = new StopWatch(); stopWatch.start(); joinPoint.proceed(); stopWatch.stop(); long totalTimeMillis = stopWatch.getTotalTimeMillis(); Signature signature = joinPoint.getSignature(); String methodName = signature.getName(); if (totalTimeMillis <= mills) { log.info("methodName: {}, 실행시간 = {}ms", methodName, totalTimeMillis); } else if (totalTimeMillis <= maxMills) { log.warn("methodName: {}, 실행시간 = {}ms", methodName, totalTimeMillis); } else { log.error("methodName: {}, 실행시간 = {}ms", methodName, totalTimeMillis); }} 3. 애플리케이션 코드 - 랜덤으로 실행시간 적용 @CheckTime(value = 2000)public String save(String itemId) { seq++; if (seq % 5 == 0) { throw new IllegalStateException("예외 발생"); } sleep(); return "ok";}private void sleep() { int[] ints = {1000, 2000,3000,4000,5000}; double random= Math.random(); int num = (int) Math.round(random * (ints.length-1)); System.out.println(ints[num]); try { Thread.sleep(ints[num]); } catch (InterruptedException e) { e.printStackTrace(); }}
- 미해결스프링 핵심 원리 - 고급편
프록시 패턴과 데코레이터 패턴의 본질적 차이
안녕하세요 강의에서 프록시 패턴과 데코레이터 패턴의 차이는 해당 패턴을 만든 의도라고 하셨습니다. 접근 제어가 목적이면 프록시 패턴이고, 부가 기능 추가 목적이면 데코레이터 패턴이라 하셨는데, 예를 들어, 프록시 패턴으로 짠 코드의 기능(캐싱)을 타임 로깅으로 바꾼다면, 해당 코드는 데코레이터 패턴으로 짰다고 봐도 무방한 것인가요? 극단적인 예시이긴 하지만, 두 패턴의 차이가 단지 의도(intent) 뿐인가 궁금하여 질문드립니다..!
- 해결됨스프링 핵심 원리 - 고급편
강의 학습 중 공통(부가)기능 처리 방법에 대한 질문입니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 아니오2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]안녕하세요. 스프링 핵심원리 고급편에서 다루는 주요 내용인 핵심기능과 공통(부가)기능을 어떻게 나눌 것인가를 듣다보니 어느덧 AOP 챕터까지 다다르게 되었습니다. 강의를 통해 부가기능의 종류에는 크게 로깅, 트랜잭션처리, 접근권한확인이 있다고 생각이 들었습니다. 이것들은 앞에서 다룬 개발 패턴이나 AOP를 사용하지 않고도 유틸리티성 클래스를 통해 처리가 가능한 것으로도 알고 있지만 SOLID 원칙, 유지보수 효율 증대, 중복 코드 제거 등의 많은 이점을 가져다주기 때문에 AOP와 같은 기술을 사용하는 것은 이해를 했습니다. 그러나 Filter/HandlerInterceptor를 사용해서도 부가기능을 처리할 수 있을 것으로도 생각이 드는데요.(스프링 MVC 강의 학습을 통해 느낀 점입니다.) 저와 비슷한 생각을 가지고 계신 다른 분께서 질문한 글의 답변을 인용하자면 웹과 관련된 공통(부가)기능(특정 메뉴 접근권한 확인, 로그인 여부 확인 등)는 Filter/HandlerInterceptor를 통해 처리하고, 순수한 자바 코드를 통한 공통(부가)기능은 AOP를 이용하는 것이 맞는 것인지 궁금합니다. (참고 질문: https://www.inflearn.com/questions/495293) 물론 더 나아가 시큐리티를 알고 있다면 이런 질문 내용도 다른 방식으로 해결이 가능하겠지만, 만약, 시큐리티를 현재 모르고 있다라는 가정하에 위와 같이 실무에서도 처리하는게 맞는지 첨언 부탁드리겠습니다. 미리 답변 감사드립니다.
- 미해결스프링 핵심 원리 - 고급편
component 중복초기화 부분 추상클래스로 변경
강사님께서 말씀주신 component 중복 호출 부분 추상클래스로 빼봤습니다. 피드백 사항 있으면 말씀 부탁 드립니다^^; Decorator - 추상클래스 public abstract class Decorator implements Component{ private Component component; public Decorator(Component component) { this.component = component; } @Override public String operation() { return component.operation(); }} MessageDecorator public class MessageDecorator extends Decorator{ public MessageDecorator(Component component) { super(component); } @Override public String operation() { log.info("MessageDecorator 실행"); //data -> *****data***** String result = super.operation(); String decoResult = "*****" + result + "*****"; log.info("MessageDecorator 꾸미기 적용 전={}, 적용 후={}", result, decoResult); return decoResult; }} TimeDecoratior public class MessageDecorator extends Decorator{ public MessageDecorator(Component component) { super(component); } @Override public String operation() { log.info("MessageDecorator 실행"); //data -> *****data***** String result = super.operation(); String decoResult = "*****" + result + "*****"; log.info("MessageDecorator 꾸미기 적용 전={}, 적용 후={}", result, decoResult); return decoResult; }} test 코드 @Testvoid decorator3() { Decorator messageDecorator = new MessageDecorator(new RealComponent()); messageDecorator.operation(); System.out.println(); Decorator timeMsgDecorator = new TimeDecorator(new MessageDecorator(new RealComponent())); timeMsgDecorator.operation();}
- 미해결스프링 핵심 원리 - 고급편
앞에서 나오는 패턴들은 실무에서 쓰이긴 하나요? (콜백, 템플렛 메서드 등)
영한님 강의 구성이 보통 A테크닉 B테크닉 C테크닉 이런식으로 점차적으로 발전시켜 나가는 수업이잖아요. 그런데 결국 마지막 완전체 기술을 알고나면 앞에서 배운 기술들은 굳이 왜 실습했나 생각이 들때가 있어서요. (단점들이 분명이 있는 기술들이라 보완된 최종 기술로 쓸수밖에 없을거같아요) 분명 그 테크닉들을 실습하면서 깊이있게 배우는 스킬들이 있을테고, 왜 이런 패턴이 생겨나게 됐는지 자연스럽게 이해돼서 좋기는 한데 지금 제 상황이 빠른 시일내에 현업 적응을 해야되는 상황이다보니 실무에 실제로 쓰이는 기술 위주로 스피드하게 보고싶어서요. 영한님 수업 7개 결제 해두었는데, 이걸 이런식으로 다 보기에는 시간이 좀 부족할거같아서 질문드립니다.
- 미해결스프링 핵심 원리 - 고급편
LogTrace 빈생성 관련
영한님 안녕하세요 강의듣는중 궁금한 점이 있어서 질문 올립니다. 그동안 저는 제가 만든 클래스의 빈생성은 클래스에서 @Component를 써서 빈으로 등록하고 Dependency로 등록하여 쓰는 클래스는 이번강의의 LogTrace빈처럼 @Configuration에 @Bean으로 등록해서 쓰곤 했는데요 LogTrace빈을 @Component로 등록하지 않고 @Configuration안에 빈으로 관리하는 이유가 있을까요? 제가 생각하기로는 아마도 LogTrace인터페이스를 상속받아 쓰는 클래스의 빈을 유연하게 변경하기 위해서 일까 하는데요 제 생각이 틀렸거나 또다른 이유가 있을까요?
- 미해결스프링 핵심 원리 - 고급편
3분 10초대 관한 질문입니다
3분 10초대에서 HelloTraceV2에서는 component scan을 쓰셨지만 FieldLogTrace에서는 직접 스프링빈에 등록을 할꺼라고 하셨는데 2개를 다르게 하는 이유가 따로 있는건가요? 그리고 컴포넌트스캔을 안쓰고 굳이 직접 스프링빈을 등록하는 이유도 궁금합니다
- 미해결스프링 핵심 원리 - 고급편
실무에서 몇 개 정도의 어떤 어즈바이저를 적용해서 사용중인가요?
영한님, 안녕하세요. DB접근기술 강의를 듣고나니, 스프링 핵심원리 강의들이 다시 떠올라서 핵심원리 복습을 하고 있습니다. 스프링 AOP 에서 여러 어드바이저를 적용해도 프록시는 하나만 생성되어 사용된다 라고 콕 찝어서 설명을 해주셨는데요. 혹시 소속되어 계신 배민이나 그 전에 경험하신 시스템에서 주로 몇 개 정도의 어드바이저를 적용했고, 대략 어떤 부가기능들이 적용되어 있었는지 알 수 있으면 좋겠습니다. (참고용으로요) 로강을 위해 데이터베이스에 정보를 기록하는 부가기능들도 본 적이 있는데, 이런 부가기능들이 모이면 시스템 성능에 영향을 줄 수 있을텐데요. 보통 성능에 문제가 생길까봐 AOP 등록을 해도 될 지 고민되는 경우가 많은데 이를 어떻게 판단할 수 있을까요? 너무 애매한 질문을 드린 건 아닌가 모르겠네요. 작은 도움될만한 정도라도 답변을 주시면 감사하겠습니다.
- 미해결스프링 핵심 원리 - 고급편
12 쳅터 실전 예제 어드바이저 호출 순서 질문
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용] 같은 @Aspect 클래스 안에 있는 어드바이저 호출순서는 @Around, @before @After @AfterReturning @AfterThrowing 이라고 알려주셨습니다. 질문1. 근데 이 강의 처럼(RetryAspect.class, TraceAspect.class) 클래스로 나눠서 @Aspect를 따로 설정한 경우에 호출순서는 어떻게 되는것인가요? 강의에서는 TraceAspect가 먼저 호출되고 (@Before 포인트컷 어노테이션이 사용된 Aspect) RetryAspect가 (@Around 포인트컷)호출되었습니다. 질문2. RetryAspect가 먼저 호출되고 TraceAspect를 호출하는 방법은 없을까요? 질문3. ExamRepository에서 seq이 5가 되는순간 IllegalStateException이 발생하면서 RetryAspcet.class가 실행되는거 같습니다. 프록시를 적용한 객체는 예외처리가 발생하면 그전 단계인 프록시로 돌아가는것이라고 이해하면 되는게 맞나요? 호출순서가 헷갈리는거 같습니다. 항상 강의를 감사한 마음으로 듣고 있습니다. 영한님과 서포터즈분께 감사합니다.
- 미해결스프링 핵심 원리 - 고급편
람다식에 대한 질문 드립니다.
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예 [질문 내용] "주의"부분을 보면 가급적이면 사용하지 않는 것이 좋다고 하셨고 람다식을 사용하는 방법이 있다는 얘기를 듣고 아래와 같이 코드를 작성 해보았습니다. 이러한 방향으로 작성해도 좋은지 궁금하여 질문 드립니다. 사실 아래와 같은 방향으로 가게된다면 많은 "인터페이스가 생기가 되는 것 같아서" 공통만 해결하고 실제 수업에 말하고자 하는 이점은 얻지 못하는 것 같아서 질문드립니다.
- 미해결스프링 핵심 원리 - 고급편
Thread local 과 Prototype bean 문의
안녕하세요 강의 감사히 잘 듣고있습니다. 이게 Request Scope 하고도 비슷한 답변일거같긴한데.. 혹시, Prototype bean 으로도 해당문제를 해결할수 있지않나요?? 무슨기준으로 어떤때는 Prototype bean 을사용하고 어떤때는 Thread local 을가지고 사용하는지가궁금합니다.
- 해결됨스프링 핵심 원리 - 고급편
LogTraceAspect 에 @Component 애노테이션을 붙여서 스프링 빈 등록하기
LogTraceAspect 에 @Component 애노테이션을 붙여서 스프링 빈 등록을 해도 된다고 하셔서 해봤는데 로그가 안나오더라구요ㅠㅠ LogTraceAspect.java -> @Aspect와 @Component 추가 AopConfig.java -> 사용 x ProxyApplication.java -> @Import({AppV1Config.class, AppV2Config.class}) @SpringBootApplication(scanBasePackages = "hello.proxy.app") 이렇게 하고 실행했는데 작동 자체는 잘 되지만 로그가 찍히지 않습니다 제가 뭘 잘못했을까요??
- 미해결스프링 핵심 원리 - 고급편
동적 프록시 SRP
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 평소 SRP는 클래스는 하나의 책임을 가져야 한다. 즉, 클래스를 변경하는 이유는 하나여야 한다 정도로 알고있었습니다. p.12 에서 '결과적으로 프록시 클래스를 수 없이 만들어야 하는 문제도 해결하고, 부가 기능 로직도 하나의 클래스에 모아서 단일 책임 원칙(SRP)도 지킬 수 있게 되었다.' 라는 부분에서 '부가 기능 로직도 하나의 클래스에 모아서 단일 책임 원칙(SRP)도 지킬 수 있게 되었다' 는 내용이 잘 이해가 되지 않습니다. 유지보수를 위해 변경지점을 한곳으로 모아야 한다는것은 이해했지만 기존의 프록시 클래스들도 변경이유는 부가기능 같은 하나의 이유라고 생각해서 SRP 를 만족하지 않을까 라는 생각을 했습니다. 이 부분과 SRP관련해서 제가 잘못 알고있는게 있는지 알 수 있을까요?
- 미해결스프링 핵심 원리 - 고급편
private method 포함한 Controller @Aspect로 AOP 적용했을때의 의문점
안녕하세요. Controller에 AOP를 적용하는 과정에서 궁금한점이 있어 질문을 올립니다. 보통 handler method 는 private 으로 지정하진 않겠지만, 만일 private으로 지정해도 handler는 정상 동작하는 것으로 알고 있고 정상 동작도 확인하였습니다. 그런데, @Aspect 이용해서 해당 Controller의 Proxy를 빈으로 등록시켰을때 문제가 발생합니다. 우선, 첫번째 예상했던 것은 CGLIB는 상속을 이용하기에 private메서드는 상속을 못해서 handler가 정상동작하지 못할 것 같았습니다. 하지만 결과는 정상동작하는 것을 보았습니다. 어떻게 정상동작이 수행가능 한걸까요? 혹시, private handler의 경우는 바로 target메서드를 찾아 실행시키나 해서 stack trace를 봐보면 Enhancer객체에서 실행되는 것을 볼 수 있습니다. 물론, 이처럼 간단한 handler라면, 정상적으로 응답이 오지만 만일 해당 handler가 의존성주입된 객체를 사용하려고 한다면 Enhancer 객체는 상태를 갖지않는 proxy객체라 NullPointerException이 발생합니다. 의문점을 정리해보자면, `private handler는 어떻게 Enhancer객체에서 수행할 수 있을까? ` 입니다. 한번 reflection은 private메서드도 수행가능하기에 상속한 슈퍼클래스의 private 메서드를 이용해 정상 동작한다. 로 가정하고 생각해봤습니다. 그러면 또 꼬리의문이 드는데 슈퍼클래스의 private메서드를 이용한다면, 실제 target 메서드이므로 DI된 객체가 null이 되는 것이 의문 입니다.
- 해결됨스프링 핵심 원리 - 고급편
OrderControllerInterfaceProxy 에는 @GetMapping 을 명시하지 않아도 되나요?
안녕하세요. bean 등록 후 테스트 할 때 url 에 아래처럼 입력하는데요. /v1/request?itemId=hello 문득 생각해보니 OrderControllerInterfaceProxy 에는 @GetMapping 이 없는데 동작하는 것을 보니 인터페이스의 구현체에는 @GetMapping 을 명시하지 않아도 되는건가요?
- 미해결스프링 핵심 원리 - 고급편
@Bean 매서드 매개변수 주입
덕분에 강의 잘 듣고 있습니다 수동으로 빈생성시 orderController매서드에 매개변수("LogTrace logTrace")는 @Autowired선언 없이 어떻게 주입이 되는지 이해를 못하겠습니다.....
- 미해결스프링 핵심 원리 - 고급편
빈 후처리 관련 질문
안녕하세요 영한님~아래와 같은 부분이 궁금하여 여쭤봅니다.#. 빈 후처리 - 스프링 컨테이너가 생성한 Bean에 대해서 스프링컨테이너에 저장하기 전에 처리되는 과정#. AnnotationAwareAspectJAutoProxyCreator ( 자동프록시 생성기 ) - implementation 'org.springframework.boot:spring-boot-starter-aop' 라이브러리를 통해서 자동 Bean으로 등록된 AnnotationAwareAspectJAutoProxyCreator 후처리기를 통해서 @AspectJ, Advisor 내 Pointcut을 확인하여 자동 Proxy 등록해줌.#. 정리를 위한 질문 1. AnnotationAwareAspectJAutoProxyCreator - 프록시만 등록해주는 빈 후처리기이므로 프록시 생성 목적이 아닌 다른 목적의 빈 후처리를 하기 위해서는 BeanPostProcessor 구현한 객체를 Bean으로 등록하여 처리하는 것이 맞는지 궁금합니다. 2. 실무에서 자주 사용하는 빈 후처리기는 주로 무엇이 있는지 주제만 알려주시면 찾아보겠습니다.
- 미해결스프링 핵심 원리 - 고급편
Aop와 Filter...
갑자기 궁금한게 생겻는데요... Filter혹은 Interceptor도 공통의 관심 기능 관련해서 처리를 해주는게 아닌가 생각이 들더라고요 어떤것을 시작하기 전에 걸러주는 역할을 하는것인데 Aop의 경우에도 어느곳에 적용할 수 있는지 제어도 가능한데 Filter도 제어가 가능하니 두개를 어떻게 비교해야 좋을지 헷갈립니다.