본문 바로가기

삽질

Spring Web의 두 가지 기본 Context Context란 무엇일까요? 스프링이 관리하는 빈(Bean)을 담아두는 컨테이너라고 생각하시면 됩니다. Spring 프로젝트를 만들면 기본적으로 두 가지 컨텍스트가 만들어집니다. 첫 번째는 ApplicationContext입니다. 두 번째는 WebApplicationContext입니다. ApplicationContext는 주로 Service, Dao등 프로젝트 전체에서 공유하는 빈들을 저장합니다. WebApplicationContext는 주로 Controller와 같이 특정 서블릿(DispatcherServlet)에서만 사용되는 빈들을 저장합니다. Spring Web Mvc에서 빈을 참조할 때, 우선적으로 WebApplicationContext를 참조 하고 빈을 찾지 못하면 ApplicationConte.. 더보기
Spring Web MVC 동작 과정 스프링으로 웹 서버를 만들면, 특별한 서블릿을 바탕으로 사용자의 응답을 받을 수 있습니다. 이 서블릿 이름이 DispatcherServlet입니다. 스프링은 이 DispatcherServlet으로 사용자의 요청을 받고, 처리한 뒤 반환을 합니다. 그림은 아래와 같습니다. 위 그림의 순서를 바탕으로 설명을 덧붙여 보겠습니다. 1. DispatcherServlet이 Client로 부터 요청을 받음 2. DispatcherServlet이 어떤 컨트롤러 메소드에 가야하는지 HandlerMapping에 물어봄 3. HandlerMapping은 url에 매턴에 맞는 Controller와 메소드의 정보를 DispatcherServlet에 제공함 4. 응답을 받은 DispatcherServlet은 Conroller에게.. 더보기
findAll과 findById 조회의 차이 한 프로젝트에서 테스트케이스를 작성하는데, findAll에서 에러가 발생했습니다. member 객체를 mock으로 생성해서 발생하는 문제였습니다. mock객체는 가짜 객체입니다. mock으로 객체를 만들면 실제 값은 null입니다. mock객체의 모든 값은 null이지만 when으로 선언하면, Mockito가 프록시 방식으로 실제 동작할 때 값 대체합니다. 💡 여기서 프록시 방식이란, 요청을 가로채서 동작하는 방식을 의미합니다. 저는 테스트케이스 내부에 아래와 같이 영속성에 추가해줬습니다. 그러면, 모든 값이 null인 member mock 객체가 영속성 컨텍스트에 저장됩니다. 💡 entityManager를 통해 영속성 컨텍스트에 접근할 수 있습니다. 아래 테스트케이스를 보면 findById는 제대로 동.. 더보기
@WebMvcTest 옵션으로 특정 클래스 지정하기 @WebMvcTest에 옵션을 지정해서 특정 컨트롤러 클래스만 빈으로 등록해서 가져오는 기능이 있습니다. 아래의 에러를 만나고 나서야 저는 이 기능을 알게 되었습니다. Error creating bean with name 'mailAuthController' defined in file 저에게는 두 개의 컨트롤러가 있습니다. @RestController @RequestMapping("/api/v1/auth") @RequiredArgsConstructor public class MailAuthController { private final SendMailUseCase sendEmailUseCase; } @RestController @RequiredArgsConstructor public class Post.. 더보기
JIT과 AOT 0. 개요 Spring Boot 3.0의 변경점을 알아보던 도중, Spring Native를 공식적으로 지원한다는 것을 알게 되었습니다. Spring Native가 뭔지 몰랐던 저는 공부하게 되었고, 그 내용을 공유하고자 합니다. 우선, Chat GPT에 Spring Native에 대해 물어 보니 아래와 같은 답변을 받았습니다. 요즘 핫한 마이크로서비스(MSA)에 유용하다고 하니 공부를 안할 이유가 없었습니다. 위 내용중 AOT(Ahead-Of-Time) 컴파일러가 네이티브 이미지 생성을하고, 이 것을 통해 초기 실행 속도 향상, 메모리 최적화, 더 적은 종속성을 만들 수 있다고 하니 이 AOT에 대해 궁금해졌습니다. AOT 컴파일러는 JIT 컴파일러와 비교하여 설명할 것이기 때문에 우선 JIT 컴파일러.. 더보기
Arrays.asList()와 ArrayList가 다른 클래스인 이유 흔히 배열을 리스트로 만들 때 Arrays.asList()를 많이 사용하실 것입니다. Arrays.asList()는 아래와 같이 선언되어 있습니다. @SafeVarargs @SuppressWarnings("varargs") public static List asList(T... a) { return new ArrayList(a); } 가변 변수인 a를 받아서 ArrayList로 변환하여 반환합니다. 이와 똑같이 배열을 만들어 우리가 잘 아는 java.util.ArrayList 생성자에 넣어보겠습니다. 위 그림과 같이 불가능 합니다. 왜 그럴까요? 그 이유는 Arrays.asList()로 만들어지는 ArrayList와 java.util.ArrayList가 다른 클래스이기 때문입니다. [java.util.A.. 더보기
main(String[] args)의 의미 0. 요약 결론부터 말하자면, 프로그램을 실행하기 전에 외부에서 main 으로 값을 넣어주기 위한 코드다. 값을 입력하는 것이라면, Scanner나 BufferedReader을 쓰면 되지 않나? 질문이 나올 수도 있다. 순서가 다르다. Scanner나 BufferedReader는 main 실행 이후에 Console 대화 창으로 값을 입력 받는 방법이다. 하지만, main(String[] args)는 외부에서 값을 받고 같이 실행된다. 1. 사용해보기 우선 인자의 값을 출력할 코드를 아래와 같이 만든다. public class Test{ public static void main(String[] args){ for(String arg : args){ System.out.println(arg); } } } .. 더보기
Java 상수 final의 초기화 방법 0. 개요 final이 붙으면, 한 번 초기화가 될 경우 그 값을 바꾸지 못하는 상수가 됩니다. 예전에는 선언과 동시에 초기화를 해야 했지만, 현재는 그러지 않아도 됩니다. 이 글에서는 상수를 어떻게 하면 초기화 할 수 있을지에 대해 알아보겠습니다. 1. 정적(static) 상수 1.1 선언과 동시에 초기화 일반적으로 정적 상수를 사용할 때에는, 선언과 동시에 초기화를 합니다. public class Test { private static final int STATIC_VALUE = 5; } 현재 상태에서 선언과 동시에 초기화를 하지 않으면 에러가 뜹니다. 1.2 정적 블럭 정적 블럭을 통해서라면 멤버 레벨에서 초기화하지 않아도 됩니다. public class Test { private static fi.. 더보기