스프링 28

잘 못 처리한 @ControllerAdvice를 수정하기

개요프로젝트에서 ControllerAdvice를 사용해서 에러를 처리하는 중 이상한 버그가 발생했다. 아래와 같이 에러가 처리되는 것이 아닌 무한로그가 찍히면서 요청이 종료되지 않는 것이다.   문제  분석 문제를 분석한 결과 ControllerAdvice에서 에러를 처리할 때 ResponseBody로 처리하지 않아 에러 부분을 스프링에서no static resource에러를 발생한 것이다.   해결 아래와 같이 ControllerAdvice클래스에 ResponseBody를 추가해 해결해 주었다.@ControllerAdvice@ResponseBodypublic class GlobalExceptionHandler {아래와 같이 에러를 옳게 처리하는 것을 확인할 수 있다.

스프링 2024.08.05

스프링에서 GPT API로 이미지 전송하기

개요스프링에서 GPT-4o API를 활용해 이미지를 전송하고 답변을 받아보자.  yml먼저 GPT 설정을 위해 yml파일을 작성하자 openai: model: gpt-4o api: key: token url: https://api.openai.com/v1/chat/completions model과 gpt 사이트에서 발급받은 key를 token에 넣어 둔 후 API를 요청할 url을 작성한다.   이미지 인코딩하기GPT에 요청을 하려면 이미지를 base64로 인코딩을 해야 한다. 이를 위해 ImageUtils 클래스를 만들어 MultipartFile이미지를 인코딩 하자 public class ImageUtils { public static String encodeImageToBase64..

스프링 2024.07.19

enum 타입(key-value)의 Json 반환, 객체를 Json 직렬화

개요프로젝트에서 enum 타입을 key-value로 사용하고 있었다. 이를 원하는 Json형식으로 변경하는 과정을 담으려고 한다. 본문프로젝트에서 지하철 라인을 enum 타입으로 관리하고 있었다.public enum SubwayLine { LINE_1("1호선"), LINE_2("2호선"), LINE_3("3호선"), LINE_4("4호선"), DONGHAE("동해선"), GIMHAE_LIGHT_RAIL("부산김해경전철"); private String lineName; 지하철 라인을 담은 Dto를 아래와 같이 작성했다고 가정하자.public class TestDto { private Long id; private String name; ..

스프링 2024.05.17

@Profile("local") 사용

개요embedded redis를 사용하기 위해 local환경에서는 embeddedRedisConfig클래스를 @Configuration으로 등록해 주어야 하 할 일이 생겼다. 이를 local환경에서만 등록되도록 설정해 보자 Profile보통 애플리케이션은 여러 환경에서 실행될 수 있다. 예를 들어 개발, 테스트, 운영 등의 환경이 있을 수 있다. 각 환경마다 필요한 설정이나 빈들이 달라질 수 있다. @Profile 어노테이션은 이러한 환경에 따라 다른 설정을 제공할 때 사용된다. @Profile("local")@Configurationpublic class EmbeddedRedisConfig {위 코드와 같이 클래스 위에 Profile 어노테이션을 추가해 준다.그 후 application.properti..

스프링 2024.05.09

request 웹 스코프와 프록시

웹 스코프는 웹 환경에서만 동작한다 그중 request 웹 스코프에 대해 알아보자. Request 웹스코프는 HTTP 요청 하나가 들어오고 나갈 때까지 유지되는 스코프이며 각각의 HTTP 요청마다 별도의 빈 인스턴스가 생성되고 관리된다. 다음 그림을 보자 클라이언트 A와B는 싱글톤인 Controller와 Service빈을 공통으로 가지고 request scope빈은 개별로 다른 인스턴스를 HTTP 요청을 할 시에 할당되어 가진다. request빈의 특징은 HTTP가 들어오고 나갈 때까지 유지되는 것이기 때문에 클라이언트 A가 Controller에서 request scope빈을 요청하고 그 후 Service에서 resquest scope빈을 요청을 또 하더라도 같은 인스턴스의 전용 request scope..

스프링 2023.07.26

프로토타입 스코프 빈과 싱글톤 빈을 함께 사용시 문제점

프로토타입 스코프 빈과 싱글톤 빈을 함께 사용하면 문제점이 발생할 수 있다. 아래 예시를 통해 알아보자. 위 그림에 프로토타입 스코프 빈은 count라는 0으로 초기화된 private 변수를 가지며 메서드 addCount()를 통해 count 값을 1 증가시킨다. 우리가 원하는 작동 방식은 클라이언트 A와 B가 각각의 프로토타입 스코프 빈을 할당받아 각각의 count값을 가지고 각자 addCount() 메서드를 통해서 1씩 증가시킨 count 1 값을 가지기를 원한다. 하지만. cilentBean은 싱글톤이고 cilentBean은 프로토타입 스코프 빈을 생성자로 의존관계를 주입받는다. 그럼 주입 시점에 스프링 컨테이너에 프로토타입 빈을 요청한다. 그럼 스프링 컨테이너는 프로토타입 빈을 생성해서 clien..

스프링 2023.07.25

프로토타입 스코프

빈 스코프란 이름 그대로 빈이 존재할 수 있는 범위를 뜻한다. 우리는 지금까지 컨테이너의 시작과 종료까지 유지되는 스코프를 가지는 싱글톤에 대해서 공부를 했다. 하지만 프로토타입이라는 스프링 컨테이너가 빈의 생성과 의존관계 주입까지만 관여하고 더는 관리하지 않는 스코프를 가지는 프로토 타입 빈이라는 것도 있다. 빈 스코프는 @Scope애노테이션을 이용해서 지정할 수 있다. 기본 디폴트 값은 singleton이다. 프로토타입은 다음과 같이 지정할 수 있다. @Scope("prototype") @Bean PrototypeBean HelloBean() { return new HelloBean(); } 싱글톤 스코프의 빈을 조회하면 스프링 컨테이너는 항상 같은 인스턴스의 스프링 빈을 반환하지만 프로토타입의 스코..

스프링 2023.07.24

빈 생명주기 콜백

데이터베이스 커넥션 풀, 네트워크 소켓처럼 애플리케이션시작 시점에 필요한 연결을 미리 해두고, 애플리케이션 종료 시점에 연결을 모두 종료하는 작업을 진행하려면, 객체의 초기화와 종료 작업이 필요하다. 스프링 빈은 객체를 생성하고 의존관계를 주입한 다음 필요한 데이터를 사용할 수 있는 준비가 된다. 그러므로 초기화 작업은 읜존관계주입이 끝난 다음에 해야 한다. 이를 위해서는 개발자는 의존관계 주입이 완료된 시점을 알아야 하는데 스프링은 의존관계 주입이 완료되거나 스프링 컨테이너가 종료되기 직전에 스프링 빈에게 콜백 메서드를 통해서 초기화 시점을 알려주는 여러 가지 기능을 제공한다. 요약하자면 스프링 컨테이너 생성 -> 스프링 빈 생성 -> 의존관계 주입 -> 초기화 콜백 -> 빈 사용 -> 소멸 전 콜백 ..

스프링 2023.07.24

동일 타입 2개 이상의 빈이 모두 필요할 때

동일 타입으로 조회한 빈이 모두 필요한 경우가 있다. 예를 들어 고객이 RateDiscountPolicy를 선택해서 할인을 받을지 FixDiscountPolicy를 선택해서 할인을 받을지 고를 수 있다고 생각해 보자. 이를 위해 같은 타입의 빈을 List나 Map으로 받아와야 한다. @Autowired public DiscountService(Map policyMap, List policies) { this.policyMap = policyMap; this.policies = policies; } 이렇게 Map과 List로 의존관계를 주입 받을 수 있다. Map에는 빈 이름이 key 인스턴스가 value로 저장된다. List에는 각 인스턴스가 저장되어 있다. 이렇게 두개의 discountPolicy를 주..

스프링 2023.07.22

조회 빈이 2개 이상일 때 주입받는 방법

@Autowired는 타입으로 조회한다 타입으로 조회하면 같은 타입의 빈이 2개 이상일 때 문제가 발생한다. 예를 들어 DiscountPolicy의 하위 타입인 FixDiscountPolicy, RateDiscountPolicy둘다 스프링 빈으로 등록시키고 @Autowired private DiscountPolicy discountPolicy 위와 같이 DiscountPolicy타입으로 의존관계를 주입하면 NoUniqueBeanDefinitionException오류가 발생한다. 해결방법으로 하위타입을 이용해서 의존관계를 주입하면 DIP를 위배하고 유연성이 떨어진다. 해결방법에는 크게 3가지가 있다. @Autowired 필드 명 매칭 @Qualifier사용 @Primary사용 @Autowired 필드 명 ..

스프링 2023.07.22