게시글
질문&답변
2024.11.09
강의 재생 안됨
영상 재생이 안 되시는 건지요. 이건 인프런의 문의하기 기능을 이용해서 인프런 운영팀에게 요청을 해주시는 게 좋겠습니다.
- 0
- 2
- 16
질문&답변
2024.11.07
Test 결과 화면이 다른 거 같은데 설정 문제일까요?
테스트를 실행하는 IntelliJ의 설정에 따라서 방식이 다르기 때문인 것으로 생각됩니다.task가 많이 뜨는 건 제가 Gradle을 이용해서 테스트를 실행하는 기본 설정으로 되어있기 때문일 겁니다. 사실 어떤 방식으로 테스트를 수행하는 거의 차이는 없습니다. 그래도 같은 화면을 보고 싶으시면 설정에서 저와 같은 방식으로, Run test using 이부분을 Gradle로 해주시면 될 듯합니다.(사진)
- 0
- 2
- 30
질문&답변
2024.11.04
NoSQL의 PlatformTransactionManager adapter 는 없는건가요?
안녕하세요. NoSQL 중에서 스프링이 지원하는 기술들은 대부분 트랜잭션 관리 기능이 구현되어있습니다. PlatformTransactionManager 추상화를 이용하고, @Transactional도 적용이 가능하죠. 사용 기술을 스프링이 지원하는지 확인해보시고, Spring MongoDB 등과 같이 제공되는 경우에는 레퍼런스 문서에서 Transaction으로 검색해보시면 사용방법을 확인하실 수 있습니다.
- 0
- 2
- 32
질문&답변
2024.10.31
스프링 부트와의 강의 순서 질문
학습 순서는 스프링 6를 먼저 들으시고, 스프링 부트로 개발하는 간단한 경험을 해보신 뒤에 스프링 부트 강의를 들으시면 좋습니다. 스프링 3.x라고 하셨는데 10년 이전에 개발된 레거시 시스템을 유지보수하시는 게 아니라면 아마도 스프링 부트 3.x를 쓰실 것 같네요. 스프링 부트를 써보지 않으셨다면 인프런의 무료 강의 또는 온라인에 공개된 간단한 스프링 부트 예제를 한번 따라 해보시고, 제 부트 강의를 들으시면 좋을 겁니다.
- 0
- 2
- 60
질문&답변
2024.10.24
ServiceLocatorFactoryBean에 궁금한점이 있습니다.
로그인 전략을 구현한 빈이 매번 새로 만들어질 게 아니라면 미리 정의해두고, 필요한 타입과 주입 정보를 이용해서 가져다 생성자, 세터 등으로 주입 받아 사용하는게 맞습니다. 의존성 주입이 가능한데 의존성 룩업을 사용할 이유는 없습니다. 매번 새로운 빈을 만드는 프로토타입이 아닌 경우라면요. 당연히 그것도 Provider 방식을 이용하면 되는데, 지금 말씀하신 로그인 전략은 그럴 필요가 없어보입니다. 다만, 이 경우 LoginStrategy를 구현한 빈이 여러개라면 주입 받을 때컬렉션으로 모두 가져와서 필요한 걸 선택해서 사용하거나사용할 로그인 방식에 따라서 bean name이나 qualifier 등으로 특정 strategy 빈을 가져와 사용하는 방식이 필요할 겁니다.강의의 어느 부분을 보시다가 이 내용이 알고 싶으셨는지 궁금하군요. 제가 답변을 드릴 수 있는 건 얼마든지 답을 해드리겠습니다만, 가능하면 강의 내용과 관련된 질문을 해주시면 감사하겠습니다.
- 0
- 1
- 46
질문&답변
2024.10.13
인용구의 출처가 궁금합니다.
조영호 님이 예전에 쓰신 블로그 글 시리즈에서 인용한 내용입니다. 그 뒤로 블로그 서비스가 종료되어서 지금은 그 글을 온라인에서는 찾을 수 없는 걸로 알고 있습니다.
- 0
- 1
- 58
질문&답변
2024.10.04
애플리케이션 예외 사용에 대한 질문
날카로운 질문을 해주셨네요. 지금 예로 드신 InsufficientBalanceException을 복구가능한 정상적인 작업흐름, 그러니까 비즈니스적으로 의미있는 설계된 플로우의 하나로 볼 것인가, 또 그게 어느 정도의 비율로 나타날 것인가 등에 따라서 사실 접근 방법은 조금씩 다른 듯합니다. InsufficientBalanceException을 정상적인 비즈니스 로직의 케이스의 하나로 보지만 극히 드물게 일어난다고 가정을 해보죠. 예를 들어 프론트에서 이미 잔고를 확인한 상태에서만 이체 요청을 한다거나 결제를 하도록 만들었는데, 하지만 그 순간 다른 결제가 돌아가면서 잔액이 부족해지는 경우가 있습니다. 아주 드물지만 없지 않죠. 비율이 얼마나 될까요. 전체 이체 요청 만 건당 하나라고 보면, 이건 예외적인 상황이 맞습니다. 그래서 이런 건 시스템 장애나 버그에 의한 예외는 아니지만 극히 예외적인 상황이라서 Exception을 사용하고 싶은 거죠. 그러면서 이런 시도를 했다는 기록을 DB에 남기고 싶다면, 체크예외를 쓸 수 있습니다. 그러면 이체 자체를 제외한 나머지 DB 작업은 트랜잭션이 커밋되면서 남게 되고, 이 예외를 앞의 Controller가 받아서 이 경우에 사용자에게 보내줄 알림을 전해줄 수 있겠죠. 그런데 이런 0.01% 수준의 예외적인 케이스를 위해서 리턴 값에 의미를 부여해서 잔액 부족은 -1. 이런식으로 정해서 이걸 if로 잡는 코드를 넣으면, 이를 처리하는 코드가 뭔가 메인이 되는 느낌이죠. 게다가 응답 값에 의미를 부여하는 것은 자칫 버그가 발생하기 쉽죠. 어떤 개발자는 이 서비스 코드를 호출하면서 0보다 작으면 에러인가 이럴 수도 있고, 어떤 개발자는 이거 상수로 정의해야 하는 거 아닌가 해서 INSUFFICIENT_BALANCE = -1 이렇게 정의해서 쓸 수도 있고, 나중에 예외 값은 -100으로 하자고 고치게 되면 로직이 틀어지겠죠. enum으로 정의할 수도 있지만, 다른 응답 값이 있는 경우에 예외 경우를 체크하기 위한 enum을 같이 리턴하려면 또 클래스로 만들어야 하죠. 그래서 이때는 체크 예외를 만들어서 이런 경우가 있을 수도 있다는 걸 사용하는 컨트롤러 등의 코드에 명확하게 알려주고, 이때 대응하는 코드를 만들도록 강제할 수 있습니다. 아마 책에서는 이걸 강조해서 설명했던 것 같습니다. 강의에서 이 케이스를 다루지는 않았지만, 핵심은 복구 불가능한 예외는 예외로 처리하고 굳이 핸들링하지 않는게 맞다는 것을 이야기했습니다. 이 잔액 부족은 복구 가능한 것일까요? 여기서 예외를 프론트엔드까지 다루는 시나리오에 따라서 여러 판단이 있을 수 있을 듯합니다. 이걸 의미있게 처리하기 위해 정상 플로우의 특별한 상황으로 정의하고 API에서 특정 응답을 주도로 만들고, 프론트는 이런 잔액부족 상황을 알게 되면 다시 최신 잔액을 확인하는 API를 호출하게 만들고, 안내를 주도록 할 수 있죠. 또는 이걸 응답에서 그래서 부족한 이유와 잔액을 이 케이스에서는 API 응답으로 만들 수도 있습니다.또는 이건 어쨌든 처리할 수 없는 예외상황이니 메시지만 딱 보여주고 말겠다면, 서비스에서부터 런타임 에러를 던지고, @ControllerAdvice에서 그 Exception에 담긴 에러 메시지를 담아서 리턴하고, 프론트는 에러 메시지를 띄워주고, 사용자는 다시 잔액 확인하러 뒤로 가고.. 등등의, 정말 예외적인 케이스니까 굳이 이걸 처리하는 코드를 복잡하게 만들지 않도록 할 수 있습니다.어쨌든 예외 상황을 리턴 값으로 다루지는 마시고, 복구 가능한 예외인지 아니면 일반적인 정말 예외 상황인지에 따라서 예외 타입을 결정해서 사용하시면 될 듯합니다.
- 0
- 1
- 45
질문&답변
2024.09.23
프로퍼티 빈의 후처리기 도입 AnnotationUtils의 사용
오, 이건 제가 몰랐던 방법이네요. 이렇게 annotation.prefix()를 바로 이용하는 게 더 간단하겠네요.
- 0
- 2
- 71
질문&답변
2024.09.20
SimpleCacheConfiguration과 빈 등록
스프링 부트 내부의 자동구성 설정은 꽤 복잡하게 다양한 옵션을 적용할 수 있도록 구성되어 있습니다. 특히 Customizer가 붙은 것들은 프로퍼티 파일과 결합해서 다양한 방식으로 기본 구성의 변경이 필요할 때 그 책임을 맡기는 용도로 사용되어지는데요. 말씀하신 것처럼 conditional 조건에 부합된 @Configuration 클래스 내부에 @Bean 팩토리 메소드가 있는데 거기 파라미터로 넘겨 받는 다른 오브젝트가 존재하지 않으면 실행될 때 에러가 나겠죠. 아마 기본 SimpleCacheConfiguration 외에 다른 자동 구성 클래스 어딘가에서 해당 프로퍼티와 커스토마이저 빈이 등록되도록 설정된 곳이 있을 겁니다. 디버거를 걸어서 @Bean 메소드 실행시점을 잡아서 보면 아마 그런 오브젝트가 들어와 있을 것입니다. 이게 어느 설정에서 만들어졌는지를 추적하려면 스프링 부트 소스코드 전체를 가져다가 검색을 해보면서 따라가봐야 하는데 꽤 복잡한 작업이라, 일단 어디선가 만들어지는 곳이 있다고만 설명을 드릴게요. 🙂
- 0
- 2
- 49
질문&답변
2024.09.20
paymentService를 호출 할때 new로 생성한다면
@Autowired 같은 것은 스프링 컨테이너가 new Paymentservice() 등을 호출해서 의존관계를 맺을 때 참고하도록 넣어주는 정보입니다. 스프링이 하는 일을 직접 코드로 만들어 본 것이 강의의 Client 클래스의 main() 메소드 코드입니다. 이건 내부에서 어떻게 오브젝트가 만들어지고 의존관계가 맺어지는지를 이해하도록 코드를 직접 넣은 것일 뿐입니다. 실제로 스프링 애플리케이션을 띄우면 이런 작업을 스프링 컨테이너가 직접 합니다. 그리고 많은 요청을 처리할 때 매번 PaymentService를 새로 만들 필요가 없기 때문에 한번 만들어진 PaymentService 오브젝트를 계속 재사용합니다. 그래서 불필요하게 오브젝트를 많이 만드는 일은 일어나지 않습니다. 일단 스프링 내부의 동작 방식을 이해하셨다면 개발자가 직접 new PaymentService() 등을 호출해서 사용할 일은 없습니다. 이런 작업을 대신 해주고, 한번 만든 오브젝트를 재사용하도록 관리해주는 등의 책임을 맞기기 위해서 스프링과 같은 프레임워크를 사용하는 것이죠.
- 0
- 2
- 94