Spring JPA를 통해 Entity 클래스를 설정하면서 지연로딩이라는 단어를 많이 들어봤을 것입니다.
이번 글에서는 Bean Class를 Lazy Loading 하여, 사용하지 전까지 ApplicationContext에 초기화하지 않는 방법에 대해 작성하겠습니다.
Lazy란
기본적으로 애플리케이션을 실행하면 ApplicationContext에 설정한 모든 bean이 생성되고 해당 bean의 종속성이 주입됩니다.
그에 반해, Lazy bean 정의가 구성된 경우 해당 bean은 사용할 때까지 생성되지 않고 종속성이 주입되지 않습니다.
즉, 사용하기 전까지 ApplicationContext에 초기화하는 것을 지연한다!
Lazy Initialization 설정을 통해 애플리케이션 시작 시 로드되는 클래스와 생성되는 bean의 수가 줄어들어 시작 시간이 크게 감소할 수 있다.
Lazy Initialization 주의할 점
- 필요한 시점까지 클래스가 로드되지 않고 bean이 생성되지 않아, 애플리케이션 실행 시 확인할 수 있는 문제를 확인할 수 없다.
- 클래스가 존재하지 않는 경우, 순환 참조, 잘못된 구성 등
- Lazy 설정한 Bean이 초기화된 후 요청을 처리하므로 시간 비용이 발생한다.
Bean Lazy 설정하기
방법 1 : @Lazy 어노테이션을 통한 설정
@Lazy
@Component
public class City {
public City() {
System.out.println("City bean initialized");
}
}
in order to initialize a lazy bean, we reference it from another one.
Lazy Loading할 빈에 어노테이션을 작성합니다. 해당 빈을 의존하는 빈에도 추가 설정이 필요하다.
왜냐하면, 다른 빈은 사용되기 위해서 의존하고 있는 빈들이 모두 초기화되어야 하기 때문에 다른 빈에도 @Lazy 설정이 필요합니다.
public class Region {
@Lazy
@Autowired
private City city;
public Region() {
System.out.println("Region bean initialized");
}
public City getCityInstance() {
return city;
}
}
Note, that the @Lazy is mandatory in both places.
With the @Component annotation on the City class and while referencing it with @Autowired:
Lazy 테스트
@RestController
public class TestController {
@Autowired
private MemberRepository memberRepository;
@Autowired
@Lazy
private LazyTest lazyTest;
@GetMapping("/test")
public String test() {
memberRepository.getMemberById(105371L);
System.out.println("LazyTest 초기화 전");
lazyTest.getText();
System.out.println("LazyTest 초기화 상태");
return "test";
}
}
@Lazy로 설정할 Bean Class를 생성자 주입으로 설정하게 되면 올바르게 지연 로딩 설정이 되지 않습니다.
생성자 주입으로 의존성을 주입하는 경우, ApplicationContext가 초기화될 때 TestController 빈이 생성자 주입으로 초기화되어 등록되어 지연로딩이 설정되지 않습니다.
이를 필드 주입으로 설정하여 처리합니다.
@Component
public class LazyTest {
@Autowired
private MemberJpaRepository memberJpaRepository;
public LazyTest() {
System.out.println("LazyTest init");
}
public void getText() {
System.out.println("Lazy Test");
}
@Lazy로 설정된 LazyTest는 사용되기 전에 초기화되지 않습니다.
lazyTest.getText()를 요청할 때 해당 빈이 생성됩니다. (LazyTest init 출력됨)
생성된 후 getText()를 수행하여 Lazy Test를 출력합니다.
참고자료
https://www.baeldung.com/spring-lazy-annotation
'Spring Framework > Spring boot' 카테고리의 다른 글
Spring BeanFactoryPostProcessor로 글로벌 @Lazy 설정 및 Bean 초기화하기 (0) | 2025.01.21 |
---|---|
스프링부트 @SpringBootTest, @ContextConfiguration, @WebMvcTest, @AutoConfigureMockMvc 주요 테스트 어노테이션 정리 (0) | 2024.11.27 |
Spring Boot Open-In-View 설정과 데이터베이스 성능 최적화, 영속성 컨텍스트 활용법 (1) | 2024.10.26 |
[SpringBoot] Spring에서 @Transactional과 try-catch 사용 시 롤백되지 않는 이유 (0) | 2024.10.09 |
[Spring] H2 In-memory 데이터베이스 설정 및 접속 방법 (3) | 2024.10.05 |