묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
의존한다는것이 무슨의미인가요?
강의를 듣다가 갑자기 궁금한게 생겨서 질문드립니다. 강의내에서,throws SQLException을 하게되면 SQLException을 의존한다고 하셨는데요.여기서 의존한다는게 어떤의미인지 모르겠습니다.. 의존성주입의 의미는 아닌거같고..이 부분에서는 의존한다는게 사용한다, 알고있다는 의미인건가요?? 어떤의미인것인지 질문드립니다..!
-
해결됨스프링 핵심 원리 - 고급편
logTrace를 파라미터로 받는 이유 ?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.InterfaceProxyConfig에서 logtrace를 파라미터로 받아오는 특별한 이유가 있을까요 ? logtrace를 이런식으로 생성자 주입으로 받아서 사용한다면 문제가 생길까요 ? 정상작동은 하는데 궁금합니다. @RequiredArgsConstructor @Configuration public class InterfaceProxyConfig { private final LogTrace logTrace; @Bean public OrderControllerV1 orderController(){ OrderControllerV1Impl controllerImpl = new OrderControllerV1Impl(orderService()); return new OrderControllerInterfaceProxy(controllerImpl,logTrace); } @Bean public OrderServiceV1 orderService(){ OrderServiceV1Impl serviceImpl = new OrderServiceV1Impl(orderRepository()); return new OrderServiceInterfaceProxy(serviceImpl,logTrace); } @Bean public OrderRepositoryV1 orderRepository(){ OrderRepositoryV1Impl repositoryImpl = new OrderRepositoryV1Impl(); return new OrderRepositoryInterfaceProxy(repositoryImpl,logTrace); } }
-
미해결재고시스템으로 알아보는 동시성이슈 해결방법
동시성 문제 해결방안
@Transactional public void decrease(Long id, Long quantity) { Stock stock = stockRepository.findById(id).orElseThrow(); stock.decrease(quantity); stockRepository.saveAndFlush(stock); }현재 강의 코드인데, 락을 사용해서 해결을 할 수도 있지만, 그냥 아래와 같이 JPQL을 사용해서 해결할 수 있지 않나요?@Transactional public void decrease(Long id, Long quantity) { Stock stock = stockRepository.findById(id).orElseThrow(); if (stock.getQuantity - quantity < 0) { throw new RuntimeException("재고는 0개 미만이 될 수 없습니다."); } stockRepository.decrease(id, quantity); }@Modifying @Query("UPDATE Stock s SET s.quantity = s.quantity - :quantity WHERE s.id = :id") public void decrease(@Param("id") Long id, @Param("quantity") Long quantity);락을 사용하는 것보다 이렇게 하는게 비용이 더 적을 것 같은데, 이렇게 하지 않는 이유를 알 수 있을까요??
-
미해결재고시스템으로 알아보는 동시성이슈 해결방법
Datasource 분리 의미
커넥션 문제가 발생할 수 있어 네임드락을 사용하는 경우 각 트랜잭션마다 Datasource를 분리해주는 것이 좋다고 하셨는데,Datasource를 분리해준다는 것은 서로 다른 DB를 사용해야 하는 것인가요?
-
미해결스프링 시큐리티 OAuth2
비대칭키 내용 중 궁금한게 있습니다.
데이터 보안 측면에서 송신자 공개키로 암호화 -> 송신자 개인키로 복호화를 한다고 적혀있는데요.수신자가 송신자의 개인키를 가지고 있다는게 보안적으로 문제가 되는게 아닌가 싶습니다. 수신자 공개키로 암호화 -> 수신자 개인키로 복호화의 오타인 것인지, 아니라면 어떻게 보안적으로 괜찮은건지 궁금합니다.
-
해결됨스프링 핵심 원리 - 고급편
ProxyApplication 질문
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.LogTrace를 @Bean등록할때 ProxyApplication 쪽에 등록한 특별한 이유는 없는건가요 ? 그냥 InterfaceProxyConfig안에 등록해도 상관은 없는거죠 ? @Configuration public class InterfaceProxyConfig { @Bean public OrderControllerV1 orderController(LogTrace logTrace){ OrderControllerV1Impl controllerImpl = new OrderControllerV1Impl(orderService(logTrace)); return new OrderControllerInterfaceProxy(controllerImpl,logTrace); } @Bean public OrderServiceV1 orderService(LogTrace logTrace){ OrderServiceV1Impl serviceImpl = new OrderServiceV1Impl(orderRepository(logTrace)); return new OrderServiceInterfaceProxy(serviceImpl,logTrace); } @Bean public OrderRepositoryV1 orderRepository(LogTrace logTrace){ OrderRepositoryV1Impl repositoryImpl = new OrderRepositoryV1Impl(); return new OrderRepositoryInterfaceProxy(repositoryImpl,logTrace); } @Bean public LogTrace logTrace(){ return new ThreadLocalLogTrace(); }이런식으로요. 생각해보면 logtrace는 proxyconfig쪽이랑은 크게 연관성이 없는거같긴한데 궁금해서요 ..
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
AuthenticationProvider 사용방법 - 빈으로 생성 질문 있습니다.
17~18분 사이에 설명에서 builder와 configuration 이 같은 ProviderManager를 가져온다고 하시는데요.디버깅된 사진을 보면 customAuthenticationProvider 추가는 8334번 providers에 추가가 되고, configuration에서 ProviderManager 가져와서 0번째 provider를 지운것은 parent 안에 있는 8340 리스트에서 제거한것처럼 보여지는데 맞을까요???
-
미해결견고한 결제 시스템 구축
전체적인 헥사고날 아키텍쳐 설명
안녕하세요, 좋은 강의 감사합니다. 제공해 주신 코드를 분석해 보고있는데요,구현한 헥사고날 아키텍쳐에 대한 다이어그램이나 설명이 있으면 이해하기 쉬울것 같은데 혹시 작성하신 게 있으실까요? 예를들어서, 이런 부분의 코드는 어디서 메시지를 가져오는지 intellij 로 검색해봐도 나오질 않아서요.package com.example.paymentservice2.payment.adapter.`in`.stream @Configuration @StreamAdapter class LedgerEventMessageHandler ( private val paymentCompleteUseCase: PaymentCompleteUseCase ) { @Bean fun ledger(): Function<Flux<Message<LedgerEventMessage>>, Mono<Void>> { return Function { flux -> flux.flatMap { message -> paymentCompleteUseCase.completePayment(message.payload) .then(Mono.defer { message.headers.get(KafkaHeaders.ACKNOWLEDGMENT, ReceiverOffset::class.java)!!.commit() }) }.then() } } } 그리고, adapter 내부의 in, out 폴더와 application 내부의 in, out 폴더의 차이점은 뭔가요?? P.S 수준 높은 코드라서 매우 좋습니다. 다른 강의도 이정도 수준이면 수강할 것 같습니다. 타강사님들의 강의는 쉬운것들이 많아서 경쟁력이 있으신것 같아요.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
3분 55초에 HelloServlet 클래스를 만들어서 스프링 테스트 실행 해봤는데 오류가 발생합니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]https://drive.google.com/file/d/1oarfNr9oWYa93-YMLIPBrK-P1yc87EQF/view?usp=drive_link해당 링크는 작성한 코드 압축 파일입니다.에러 메세지는 Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.라고 뜨구요 APPLICATION FAILED TO START 라고 나옵니다. 구글링 하면서 찾아보다 어떻게 해결하는지 모르겠어서 질문 남깁니다.
-
해결됨스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
SpringMemberControllerV2 핸들러 매핑 과정이 궁금합니다
처음엔 스프링이 @Controller가 붙어있는 SpringMemberControllerV2를 스프링 빈으로 등록하고 @RequestMapping옆에 있는 url 정보를 인식해서 담아둡니다. 그 다음url요청("/spring/mvc/v2/members/new-form")이 오면 DispatcherServlet이 RequestMappingHandlerMapping을 이용하여 handler(SpringMemberControllerV2)를 반환 받고 사용할 수 있는 어댑터를 조회해서 RequestMappingHandlerAdapter를 반환 받습니다. DispatcherServlet은 어댑터를 실행하여 SpringMemberControllerV2 객체에서@RequestMapping("/spring/mvc/v2/members/new-form")이 붙은 메서드를 실행합니다. 라고 이해했는데 틀린 부분이 있으면 수정 부탁드립니다.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
혹시 현업에서도 예외 테스트 시, Assertions.assertThrows 를 많이 사용하나요?
@Test void 상품주문_재고수량초과() throws Exception { //given Member member = createMember(); Item item = createBook("시골 JPA", 10000, 10); int orderCount = 11; //when // orderService.order(member.getId(), item.getId(), orderCount); //then Assertions.assertThrows(NotEnoughStockException.class, () -> orderService.order(member.getId(), item.getId(), orderCount),"재고 수량 부족 예외가 발생해야 한다."); }Assertions.assertThrows 사용 시 파라미터 자체에 로직을 넣어줘야 해서, JUnit4 의 expected 옵션과 다르게 테스트의 when 항목을 적지 않아도 되는 상황이 발생하는 것 같아서요. 현업에서도 이 방식을 주로 사용하시나요?(+ 추가 질문)junit 과 assertj.core 라이브러리를 함께 쓰는 경우엔 이렇게 한 쪽을 지저분하게 쓸 수 밖엔 없나요? (isEqualTo와 assertThrows를 하나의 테스트 클래스에서 같이 쓰는 경우) @Test void 주문취소() throws Exception { //given Member member = createMember(); Book item = createBook("시골 JPA", 10000, 10); int orderCount = 2; Long orderId = orderService.order(member.getId(), item.getId(), orderCount); //when orderService.cancelOrder(orderId); //then Order getOrder = orderRepository.findOne(orderId); org.assertj.core.api.Assertions.assertThat(getOrder.getStatus()).isEqualTo(OrderStatus.CANCEL); org.assertj.core.api.Assertions.assertThat(item.getStockQuantity()).isEqualTo(10); }
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
회원가입 테스트 에러
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예[질문 내용]여기에 질문 내용을 남겨주세요. 다음과 같은 에러가 발생합니다 이유가 궁금합니다
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
윈도우 빌드
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]JDK은 21로 Gradle은 8.5로 맞췄는데요 gradlew build하면 BUILD FAILED가 뜨지만 localhost:8080은 잘작동합니다. 파일경로에는 한글포함안되어있고 gradlew clean build해도 동일한 오류가 발생합니다. 해당 오류가 왜 발생하는지 그냥 진행해도 되는지 궁금합니다.
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
15강 rest 인증 성공 핸들러 관련 문의
안녕하세요. 선생님 학습중에 에러가 발생하여 문의드립니다. 인증 성공 핸들러에 onAuthenticationSuccess 메소드로 넘어 오는데 authentication.getPrincipal() 의 타입이 java.util.ImmutableCollections$List12 로 와서 AccountDto로 cast가 안되는 에러가 발생하는데 원인을 모르겠습니다. ㅠㅠ 에러 내용java.lang.ClassCastException: class java.util.ImmutableCollections$List12cannot be cast to classcom.test.security.domain.dto.AccountDto (java.util.ImmutableCollections$List12 is in module java.base of loader 'bootstrap'; com.test.security.domain.dto.AccountDto is in unnamed module of loader 'app') 에러 발생한 부분AccountDto accountDto = (AccountDto) authentication.getPrincipal();
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
http 요청 메세지를 서버에서 가공할 일이 생기면 어떻게 하시나요?
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 네2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 네3. 질문 잘하기 메뉴얼을 읽어보셨나요? 네[질문 내용]안녕하세요. 영한님 강의 언제나 잘 듣고 있습니다 ㅎㅎ강의를 들으면서 궁금증이 하나 드는데요. 만약 http 메세지를 서버에서 가공할 일이 생기면 어떻게 가공하시는지 궁금합니다.예시에 나오는 방법은 모두 매핑 방식인데요.예를 들어,클라이언트에서는 현재 시간이 서버로 전달됩니다.17시 1분도, 17시 59분도 같은 데이터를 조회해야 할 때, 애플리케이션에서 데이터를 조작하거나 sql로 데이터를 조작해야 할 것 같아서요. 이렇게 데이터를 조작해야 할 때 어떤 방법을 채택하시는지 궁금합니다.dto에서 생성자를 만들어 조작해야 할까요? 아니면 조작 메서드를 따로 만들어야 하는지, aop 같은 걸로(될지는 모르겠지만..) 조작해야 하는지 궁금합니다.
-
미해결토비의 스프링 6 - 이해와 원리
BeanFactory 의존관계
@Configurationpublic class ObjectFactory { @Bean public PaymentService paymentService () { return new PaymentService(exRateProvider()); } @Bean public ExRateProvider exRateProvider() { return new WebApiExRateProvider(); }} 여기서 Bean 어노테이션을 붙이면 paymentService가 호출되지 않아도 paymentService와 exRateProvider의 의존관계가 설정이 되는게 맞나요?? 만약 exRateProvider에만 Bean 어노테이션을 붙이지 않으면 어떻게 되는 건가요??
-
미해결재고시스템으로 알아보는 동시성이슈 해결방법
네임드락 부모에(facade) 트랜잭션이 없을때
자식 service 메서드에 Propagation.REQUIRES_NEW속성은 그럼 필요 없는건가요? public class NamedLockStockFacade { private final LockRepository lockRepository; private final StockService stockService; public void decrease(Long id, Long quantity) { try { lockRepository.getLock(id.toString()); stockService.decrease(id, quantity); } finally { lockRepository.releaseLock(id.toString()); } } } ----------- @Transactional public void decrease(Long id, Long quantity) { Stock stock = stockRepository.findById(id).orElseThrow(); stock.decrease(quantity); stockRepository.saveAndFlush(stock); }이렇게 자식에만 트랜잭션이 걸려있으면, 커밋이 다되고 lock 풀리는거아니에요? 굳이 부모에 트랜잭션 붙이고 자식트랜잭션에서 NEW하는 이유가 있나요?
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
세션 타임아웃과 refresh token
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]기존에 JWT의 access token과 refresh token 플로우를 알고 있는 상태에서 세션관련 강의를 듣다보니까 의문점이 생겼습니다. 강의에서 세션은 세션 타임아웃 설정을 통해 예를 들어 접속할때마다 세션 유효 기간을 30분씩 늘리는 방식으로 사용하여 세션 탈취로부터 보안을 강화하고 사용자의 빈번한 재로그인을 방지합니다.그렇다면 여기서 JWT도 세션과 유사하게 refresh token을 사용하지 말고 accesstoken을 통해 서버에 접근할때마다 유효시간을 30분씩 늘리는 방식으로 동작하면 더 효율적일거 같은데 굳이 refresh token을 활용하는 이유가 있을까요??
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
intellij JVM설정 질문
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]인텔리제이의 설정화면 두곳이 있습니다.하나는 settings > build, Execution, Deployment > build Tools > Gradle > 맨 하단 Gradle JVM 다른 하나는 project Structure > project settings > project > sdk 위 두 곳은 어떤 차이점이 있는 것인지 알고싶습니다.둘다 JDK경로를 지정하는 것처럼 보이는데 Dependency requires at least JVM runtime version 17 에러를 마주했을 때 후자에서 해결을 해보려고 해도 해결이 안됐었습니다.
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
build.gradle에 queryDSL 설정이 잘되지 않습니다.
plugins { id 'java' id 'org.springframework.boot' version '3.3.1' id 'io.spring.dependency-management' version '1.1.5' } group = 'jpabook' version = '0.0.1-SNAPSHOT' java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } //롬복 셋팅 configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-devtools' implementation 'junit:junit:4.13.1' implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.9.1' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'com.fasterxml.jackson.datatype:jackson-datatype-hibernate5' implementation 'javax.persistence:javax.persistence-api:2.2' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' //test 롬복 testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' //Querydsl 추가 implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta" annotationProcessor "jakarta.annotation:jakarta.annotation-api" annotationProcessor "jakarta.persistence:jakarta.persistence-api" } tasks.named('test') { useJUnitPlatform() jvmArgs '-Xshare:off' // JVM 아규먼트 설정 } clean { delete file('src/main/generated') }이렇게 설정해둔 상태인데 gradle을 다시로드했음에도 other에 compilequerydsl 설정이 생기지 않는 상황이고, 다른방식으로 설정도 했었는데, 그때는 또 우측 gradle의 other에 compileQeurydsl 설정이 보여서 설정을 진행했고 프로젝트 generated 디렉토리가 생성되긴 했지만, generated 디렉토리 하위 파일들이 보이지 않습니다. 어떻게 해결할 수 있을까요? 커뮤니티의 내용들을 다 참고했지만 되지 않네요..