묻고 답해요
169만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결마이크로서비스 디자인 패턴 완벽 가이드
pg사가 있다고 가정하면
제공되는 예제 파일에 대한 실행에 관련 질문을 해 주실 때는, 자신이 사용하는 운영체제(OS), 운영체제 버전, JDK 버전, IDE와 같은 개발 도구의 버전 등을 상세알려 주시면, 답변을 드리는데 도움이 됩니다. 안녕하세요.강의를 보고 있는 개발자입니다.질문이 있어 문의드립니다.만약 pg사 연동이 들어간다고 가정하면 어떤 식으로 사가를 구성해야할까요?주문서버, 결제서버, 재고서버가 있다고 가정하면대략적인 결제 흐름이 대부분 아래와 같을텐데장바구니에서 구매하기 누르면 주문서페이지로 감주문서 페이지에서 쿠폰 등을 선택하고 결제하기를 누르면 pg결제창이 뜸pg결제를 하면 결제 승인 api를 서버가 호출아래와 같이 해도 되나요.장바구니에서 구매하기 누르면 주문서버에 주문서를 생성주문서페이지에서 결제하기 누르면 주문서를 검증하고 임시결제 생성 및 pg사 url 생성 (주문서버 -> 결제서버 -> pg사 동기식으로 호출 해야할 거 같음)pg결제가 승인되면 결제서버의 결제 승인 api 호출 (임시결제를 결제완결상태로 만들고 pg사의 승인 api 호출)결제 완료되면 결제 완료 이벤트 발행하여 재고 줄인다.제가 생각하기에 pg사 결제 url 만드는 2번이 주문서버 -> 결제서버 동기식으로 호출하는게 맞는게 아닌가 싶어서 저렇게 했는데 혹시나 비동기로 할수 있는 방법이 있을까요?아니면 제가 생각한 방식말고 다른 방식이 있을까요?강의에서는 pg사 관련된 내용이 안나와 궁금하여 질문드립니다.
-
미해결스프링 핵심 원리 - 고급편
SpringBoot 4.0.6 버전에서 PackageLogTracePostProcessor exception
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]안녕하세요 영한님. 좋은 강의 만들어주셔서 감사합니다.다름이 아니라, 제가 "77강 빈 후처리기 - 적용" 강의 내용을 따라가면서 겪은 exception 에 대해 공유드리고자 글 작성합니다.@Slf4j public class PackageLogTracePostProcessor implements BeanPostProcessor { private final String basePackage; private final Advisor advisor; public PackageLogTracePostProcessor(String basePackage, Advisor advisor) { this.basePackage = basePackage; this.advisor = advisor; } @Override public @Nullable Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { log.info("param beanName={} bean={}", beanName, bean.getClass()); // 프록시 대상 여부 체크 // 프록시 적용 대상이 아니면 원본 그대로 진행 String packageName = bean.getClass().getPackageName(); if (!packageName.startsWith(basePackage)) { return bean; } // 프록시 대상이면 프록시를 만들어서 반환 ProxyFactory proxyFactory = new ProxyFactory(bean); proxyFactory.addAdvisor(advisor); Object proxy = proxyFactory.getProxy(); log.info("create proxy: target={} proxy={}", bean.getClass(), proxy.getClass()); return proxy; } } 제가 강의 내용을 따라하면서 작성한 PackageLogTracePostProcessor 파일인데, 이 상태로 실행하면 Failed to instantiate [hello.proxy.app.v1.OrderControllerV1]: Illegal factory instance for factory method 'orderControllerV1'; instance: jdk.proxy2.$Proxy56 이라는 내용과 함께 exception 이 발생합니다. 이에 대한 원인은 아래와 같이 파악했습니다. AppV1Config 에 붙어있는 @Configuration 은 proxyBeanMethods 속성이 default 로 true 이며, 이로 인해 Spring Boot 는 AppV1Config 를 감싸는 CGLIB 프록시 객체를 생성합니다. (이하 AppV1Config::CGLIB 객체로 칭하겠습니다.)이후 AppV1Config::CGLIB 객체는 PackageLogTracePostProcessor 로 들어오게 되고, ProxyFactory 를 통해 한번 더 프록시 객체로 감싸지게 됩니다.이 때, AppV1Config::CGLIB 객체는 EnhancedConfiguration 라는 인터페이스를 구현하는 상태이며, 따라서 JDK Dynamic Proxy 객체로 생성이 됩니다.**앞선 강의에서 설명해주신 대로, JDK Dynamic Proxy 프록시 클래스는 원본 클래스와는 관련이 없습니다. (동일한 인터페이스만 구현하므로)그래서 이후 AppV1Config 내부에 선언된 orderControllerV1 빈 객체를 생성하려 할 때, SimpleInstantiationStrategy.java 의 instantiate 메소드 내부에 있는 if (factoryBean != null && !factoryMethod.getDeclaringClass().isAssignableFrom(factoryBean.getClass())) 조건문에 걸려 BeanInstantiationException 이 발생하는 상황입니다. 혹시 제가 파악한 내용에 잘못된 부분이 있을지, 아니라면 이에 대한 적절한 대응 코드가 추가되어야 할 것 같은데, 한번 검토해주시면 감사하겠습니다!
-
미해결떠먹여주는 객체지향 디자인 패턴 - by 얄코
강의 순서에 대한 궁금증
안녕하세요 얄코님객체지향 프로그래밍 섹션 수강 후 디자인 패턴 섹션을 수강하려 하는데 notion의 샘플 코드를 보면Creational PatternsStructural PatternsBehavioral Patterns으로 분류하여 나열해놓으셨는데, 강의 순서는 위의 분류와 상관없이 나열되어 있더라구요.강의 순서에 의도가 있을까요?별다른 의도가 없는 경우 위에서 분류된 패턴별로 강의를 들어볼까 하여 질문드립니다.
-
미해결스프링 핵심 원리 - 고급편
어드바이스 순서 디폴트 기준이 궁금합니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.@Aspect 에서 @Order 를 따로 지정하지 않은 디폴트 기준으로, 로그/트랜잭션 선언 순서를 반대로 해도 로그가 먼저 찍히던데,디폴트 기준이 궁금합니다.포인트컷의 기준이 더 광범위한게 먼저 실행되는 느낌인데 이게 맞을까요?
-
미해결스프링 핵심 원리 - 고급편
AspectV1 예제를 @Configuration 수동 등록으로도 가능한가요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 아래처럼 작성을 해서 돌려보니OrderRepository, OrderService 가프록시가 아닌, 실제 클래스 자체가 등록되는 것 같던데, 현재 예제에서 수동 빈 등록은 안되는걸까요??? @Slf4j @SpringBootTest public class AppTest { private final OrderService orderService; private final OrderRepository orderRepository; @Autowired public AppTest(OrderService orderService, OrderRepository orderRepository) { this.orderService = orderService; this.orderRepository = orderRepository; } @Test void aopInfo() { log.info("isAopProxy, orderService = {}", AopUtils.isAopProxy(orderService)); log.info("isAopProxy, orderRepository = {}", AopUtils.isAopProxy(orderRepository)); } @Test void success() { orderService.orderItem("itemA"); } @Test void exception() { Assertions.assertThatThrownBy(() -> orderService.orderItem("ex")) .isInstanceOf(IllegalStateException.class); } @Configuration static class AopTestConfig { @Bean public OrderRepository orderRepository() { return new OrderRepository(); } @Bean public OrderService orderService() { return new OrderService(orderRepository()); } @Bean public AspectV1 aspectV1() { return new AspectV1(); } } }
-
미해결스프링 핵심 원리 - 고급편
구체 클래스를 상속받아 확장한 형태도 클래스패턴/데코레이터 패턴이라고 칭하나요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.이렇게 상속을 통해 확장하여 구현하는 형태도 프록시 패턴/데코레이터 패턴이라고 같이 칭하는 걸까요?!
-
미해결스프링 핵심 원리 - 고급편
TraceTemplate 을 미리 빈으로 등록해서 사용할때 이렇게 설정하는게 맞는건가요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 아래처럼 등록해서 의존성 주입하면문제없이 실행 되는것 같은데, 미리 빈으로 등록해서 의존성 주입하라는게 이렇게 코드를 작성하라는 말씀이셨던게 맞을까요?!@Configuration public class LogTraceConfig { @Bean public TraceTemplate traceTemplate() { return new TraceTemplate(threadLocalLogTrace()); } @Bean public ThreadLocalLogTrace threadLocalLogTrace() { return new ThreadLocalLogTrace(); } }
-
미해결스프링 핵심 원리 - 고급편
Decorator 에서 추상메서드로 뺄때 질문 있습니다.
1) 실제 로직@Slf4j public class TrueComponent implements Component { @Override public String operation() { log.info("TrueComponent 가 실행되었습니다."); return "data"; } }2) 추상클래스@Slf4j public abstract class AbstractorDecorator implements Component { private Component component; public AbstractorDecorator(Component component) { this.component = component; } @Override public String operation() { log.info("AbstractorDecorator.operation() 실행"); String result = component.operation(); log.info("AbstractorDecorator.operation() 종료"); return result; } }2) 자식@Slf4j public class DecoratorTest1 extends AbstractorDecorator { public DecoratorTest1(Component component) { super(component); } @Override public String operation() { log.info("DecoratorTest1.operation() 실행"); super.operation(); log.info("DecoratorTest1.operation() 실행"); return "data"; } }3) 자식 @Slf4j public class DecoratorTest2 extends AbstractorDecorator { public DecoratorTest2(Component component) { super(component); } @Override public String operation() { log.info("DecoratorTest2.operation() 실행"); super.operation(); log.info("DecoratorTest2.operation() 실행"); return "data"; } }4) 테스트 코드@Slf4j public class DecoratorPatternTest2 { @Test void abstractDecorator() { Component trueComponent = new TrueComponent(); DecoratorTest2 decoratorTest2 = new DecoratorTest2(trueComponent); DecoratorTest1 decoratorTest1 = new DecoratorTest1(decoratorTest2); DecoratorPatternClinet decoratorPatternClinet = new DecoratorPatternClinet(decoratorTest1); decoratorPatternClinet.execute(); } }질문))) MessageDecorator, TimeDecorator 의 중복부분인private Component component; public AbstractorDecorator(Component component) { this.component = component; }해당 부분을 줄이기 위해서 추상메서드로 올렸는데추상메서드로 올리고 코드를 실행하면 추상메서드의 log.info("AbstractorDecorator.operation() 실행"); 이부분이 어쩔수 없이 중복으로 호출되는데, 코드를 줄이기 위해서 사용하기 때문이 중복으로 호출되는건 상관이 없는 건가요?
-
해결됨C개발자를 위한 최소한의 C++
인터페이스 상속과 추상 자료형 2:00 질문
강의 자료 106p에 파생 클래스는 기본 클래스의 멤버 변수를 직접 변경하는 것은 적절치 않다고 되어있습니다.여기에서는 기본 클래스의 deviceId를 파생 클래스의 생성자에서 변경하는데 위험성이 없을까요?아니면 포인터나 참조 변수를 직접 변경하는게 위험한 것이고, 이런 일반 멤버 변수들은 괜찮은 것일까요?항상 좋은 강의 감사합니다.
-
미해결스프링 핵심 원리 - 고급편
대상 클래스에 기본 생성자가 없을 때
제목과 같은 상황에서 어떻게 될지 궁금해서 테스트를 진행해봤습니다. @Component public class Test { public Test(MemberService memberService) { } } // ================================================= @Aspect public class TestAspect { @Before("execution(* hello.aop..*.*(..))") public void doTrace(JoinPoint joinPoint) { } } // ================================================= @Slf4j @SpringBootTest(properties = {"spring.aop.proxy-target-class=true"}) @Import(TestAspect.class) public class ProxyTest { @Autowired Test test; @Test void test() { log.info("class={}", test.getClass()); } }필드 test에 class=class hello.aop.test.Test와 같이 원본 객체가 주입된 것을 확인할 수 있습니다. 이러한 순서로 흘러가는 게 맞을까요?처음에 생성된 원본 Test 빈이 AutoProxyCreator에 전달된다포인트컷에 맞는 조건이므로 CGLIB로 프록시 생성 시도CGLIB 내부에서 원본의 기본 생성자를 (호출할 수 없어서?) (찾을 수 없어서?) -> return 원본결국 반환된 원본이 빈으로 등록 추가) 다음 강의를 듣고왔는데 이해가 안되는 부분이 있습니다.스프링 4.0부터 기본 생성자가 필수인 문제가 해결되었다고 하는데 왜 위의 테스트에서는 프록시 객체가 아닌 원본 객체가 주입되었나요?
-
해결됨C개발자를 위한 최소한의 C++
13분 42초의 예제
안녕하세요. 우선 질 좋은 강의에 감사인사부터 드립니다. 우선 저는 MacOS 환경에서 Clang 컴파일러 환경에서 강의를 듣고 실습을 따라하고 있습니다. C++ 버전은 동일합니다. 그런데 강의 속 13분 42초의 예제에서 콘솔 출력 결과가 다음과 같이 나오는데요?TestData(int) testFunc() TestData(const TestData&) ~TestData(20) ~TestData(100) End of main()그런데 저의 환경에서는 임시 객체의 소멸자 메소드가 출력하는 내용의 순서가 100이 먼저 등장합니다.TestData(int) testFunc() TestData(const TestData&) ~TestData(100) ~TestData(20) End of main()이렇게 콘솔 출력이 달라지는 이유가 컴파일러 환경의 차이일까요..?개인적인 생각으로는 컴파일러를 다른 것을 사용하더라도 임시객체가 생성과 소멸되는 순서는 동일해야 할 것 같은데.. 헷갈려서 질문드립니다! 그런데 위 예제가 21분 28초에 나오는 예제랑 동일한 것 같은데, 또 강의속에서도 해당 예제는 ~TestData(100)이 먼저 출력되네요..?
-
해결됨카카오 면접관이 알려주는 반드시 알아야하는 Distributed Environment
강의 순서
안녕하세요, 미래에 네이버에 취업할 취업준비생입니다.다름 아니라, 이번 미니 프로젝트로 msa 환경을 바탕으로 하는 프로젝트를 기획중에 있습니다.msa에 대해 무지해서, 어떤 것부터 차례대로 강의를 수강하면 좋을지 말씀을 듣고싶어서 질문 남깁니다.저는 웹 프로젝트를 준비 중에 있고, 언어로는 java를 사용, spring boot를 이용해서 개발하려고 합니다.추가적으로 결제시스템까지 도입예정에 있어서, 후에 kafka 도입까지 고려하고 있습니다. 감사합니다.
-
미해결마이크로서비스 디자인 패턴 완벽 가이드
읽기 모델을 조회 최적화하여 성능 향상 하는 방법
안녕하세요.CRQS 패턴 5:33에표에는읽기 모델을 조회 최적화하여 성능 향상 하는 방법라고 나와있는데질문 1섞여있으면 최적화를 못하나요?질문 2분리를 함으로써 가능한 최적화 방법이 어떤게 있는건가요..?
-
해결됨C개발자를 위한 최소한의 C++
네임스페이스 스코프 내에서 정의된 변수, 함수들이 위치하는 곳 질문
안녕하세요! 질 좋은 강의에 감사인사부터 드립니다!해당 강의에서 네임스페이스 내부에 정의되는 변수, 함수들이 비록 특정(강의 속에서는 Test 라는) 네임스페이스에 소속되어 있기는 하지만 전역 변수 및 전역 함수로 간주된다고 하셨는데요! 그러면 디폴트로 제공되는 네임스페이스(ex. std) 또는 사용자가 새롭게 정의하는 네임스페이스 영역 내에서 정의되는 변수, 함수들은 스택과 힙 메모리 중 힙 메모리 영역에 저장되는 걸까요!?
-
미해결스프링 핵심 원리 - 고급편
스프링 부트 버전 4.0 aop 의존성 명칭 변경
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]안녕하세요 영한님 항상 강의 잘 보고 있습니다.다름이 아니라 12월 18일자 기준으로 https://start.spring.io/ 에서 제공하는 스프링 버전이 4.0.0으로 변경되었는데요, build.gradle에 aop 관련 의존성을 추가할 때 implementation 'org.springframework.boot:spring-boot-starter-aop'에서 implementation 'org.springframework.boot:spring-boot-starter-aspectj'로 의존성 명칭이 변경된 것 같습니다! 강의 자료에 첨부해주시면 좋을 것 같아서 글 남깁니다. 관련 문서도 같이 첨부드립니다.https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-4.0-Migration-Guide감사합니다.
-
미해결간단하게 알아보는 React 디자인 패턴
강의가 겹치는건가요?
Container & Presentation 강의랑 customHook 강의가 겹치는건가요? 같은영상이네요
-
미해결마이크로서비스 디자인 패턴 완벽 가이드
Orders에 테이블의 용도
Order 서비스에서 Command가 실행되면 ORDERS_EVENT에 이벤트가 저장되고 Query가 실행되면 ORDER_EVENT에서 이벤트를 읽어 데이터의 최종상태를 읽는다는것으로 이해했는데요..! 그렇다면 ORDERS 테이블은 실질적으로 사용되지 않는다고 이해하면될까요..?
-
해결됨C개발자를 위한 최소한의 C++
소멸자 가상함수 질문
안녕하세요. 57. 소멸자 가상화 강의 보고 질문드립니다.가상함수에서 virtual 예약어를 붙인 메서드는 자기부정을 전제로 파생 클래스에 동일한 이름의 함수가 만들어진다면 기본 클래스에 virtual로 선언된 가상함수는 무시되는 걸로 이해했습니다.그런데 소멸자에 virtual을 붙일 경우에는 왜 파생 소멸자만 불리는게 아니라 기본 클래스 소멸자도 불리는 걸까요?
-
해결됨C개발자를 위한 최소한의 C++
이동생성자의 매개변수로 넘어가는 임시객체의 값 유지 관련하여 질문이 있습니다.
안녕하세요.이동시멘틱 강의를 보다가 의문이 있어 문의드립니다.강의에 나오는 CMyString 클래스는 내부 포인터 변수 멤버를 가지고 있는데, CMyString a,b,c;에서 a = b+c;를 실행할 때CMyString operator+() 함수의 return값의 사본이 임시객체에 저장되고 이 임시객체가 이동생성자의 매개변수에 들어가는 것이 맞을까요?만약 그렇다면 사본을 가진 임시객체의 포인터 변수 멤버의 값이 return 값의 포인터 변수 멤버의 값과 같을텐데 return 후 return값이 소멸함에도 이동생성자 내부에서 사본은 어떻게 계속 값을 유지하는걸까요?이동생성자 호출 시에는 이동생성자 종료 전까지 return 값이 사라지지 않는걸까요?사본이라고 표현하신 것의 의미도 궁금합니다...사본은 모든게 다 똑같은 복사본인걸까요..?근데 그러면 참조자와 같은것일것같은데 반환형식이 참조자는 아니고... shallow copy한 것도 아니고 deep copy한 것도 아닌것 같은데...너무 헷갈리네요...감사합니다.
-
미해결마이크로서비스 디자인 패턴 완벽 가이드
MSA 아키텍쳐 프로젝트 구성 방식
안녕하세요 강사님질문을 드리고 싶은 부분이 있는데요MSA 아키텍쳐로 개발할 때 각각의 서비스 마다 단일 배포할 수 있다는 장점이 있다고 들었는데그러면 MSA 아키텍쳐로 개발을 진행할 때 보여주신 것 처럼 하나의 큰 프로젝트 안에 각각의 마이크로 서비스를 넣어서 만드나요? (모노레포?)혹은 각각의 마이크로 서비스를 독립적으로 만드는건가요? (폴리레포?)만약 둘 다 사용한다면 주로 사용하는 방식은 어떤 방식인가요?