[TIL] @Controller vs @RestController, JPA reflection에…
in TIL on Til, Java Last modified at:
2025-04-18 TIL
📝 TIL (Today I Learned)
🔗 원본 이슈: #43
📅 작성일: 2025-04-18
🔄 최종 수정: 2025년 04월 22일
🍀 새롭게 배운 것
1️⃣ @Controller
vs @RestController
- @Controller
- View를 반환하기 위해 사용
- 하지만 Data를 반환해야 하는 경우도 있음
- 이때는 @ResponseBody 어노테이션을 사용해야함
- @RestController
- @Controller + @ResponseBody
- JSON 형태로 객체 데이터를 반환하는 것
- 참고 URL
2️⃣ JPA reflection에서의 @NoArgConstructor
@NoArgsConstructor, @AllArgsConstructor의 동시 필요성의 차이를 알아보다가 @NoArgsConstructor는 JPA의 reflection과 관련이 있다는 것을 알게 되어 좀 더 공부해보았다.
- JPA는 객체를 생성할 때 reflection을 사용하기 때문에 “기본 생성자(파라미터 없는 생성자)”가 반드시 필요하다.
- 따라서 JPA는 @NoArgsConstructor가 꼭 필요함!
- reflection이란?
- 자바에서 코드 자체를 런타임(실행 중)에 들여다 보고 조작하는 기능
- 예를 들면
- 어떤 클래스인지 모르는데도 필드, 메서드, 생성자를 꺼내서 확인하거나,
- private 필드에도 강제로 접근하거나,
- 생성자를 호출해서 객체를 만들 수 있음
- JPA에서 리플렉션이 필요한 이유
- JPA는 직접
new
로 객체를 만들지 않음
- 내부적으로 Hibernate가 리플렉션을 사용해 객체를 생성하고 필드 값을 채워 넣음
- 그래서 기본 생성자(
@NoArgsConstructor
)가 반드시 필요한 것- 예시
User user = entityManager.find(User.class, 1L);
- 이 내부에서는 Hibernate가 리플렉션으로
User.class.newInstance()
로 기본 생성자 호출- 리플렉션으로 각 필드 값 설정
- Spring의 DI와 리플렉션의 관계
- Spring은
@Component
,@Service
같은 에너테이션이 붙은 클래스들을 자동으로 Bean으로 등록하는데, 이때 객체를 직접new
하는게 아니라 리플렉션으로 객체를 생성한다.- 예제
@Service public class HelloService { public void hello() { System.out.println("Hello from Spring Bean!"); } }
- Spring이 Bean을 만들 때 내부적으로 하는 일 (비공식 흐름)
Class<?> clazz = HelloService.class; Object bean = clazz.getDeclaredConstructor().newInstance();
- 리플렉션으로 객체를 만들고, 그걸 Spring Container에 등록해서 DI해주는 것!