@Lazy와 @Eager

바그다드·2023년 7월 13일

팀프로젝트를 하면서 jpa를 활용해 db에서 데이터를 가져올 때 엔티티에서 다른 엔티티를 참조하는 경우 lazy를 활용하였는데, lazy로 설정된 참조 엔티티의 경우 프록시 객체가 임시로 주입되고 실제로 참조 엔티티를 사용할 경우에 쿼리를 한번 더 실행해 참조 엔티티를 주입하는 방식이다.

이와 마찬가지로 스프링에서도 @Lazy와 @Eager가 있는데 두 어노테이션이 어떤 차이가 있는지 확인해보자.

Lazy InitializationEager Initialization
초기화 시점빈이 어플리케이션에서 처음 사용될 때어플리케이션이 시작할 때
기본값XO
적용방법@Lazy
@Lazy(value=true)
따로 명시하지 않아도 됨
또는 @Lazy(value=false)
초기화 에러 시점runtime exception발생어플리케이션이 실행되지 않음
사용빈도거의 사용되지 않음대부분 eager사용
메모리 사용량빈이 초기화되기 전까지
메모리를 덜 차지함
비교적 많은 메모리 사용
권장거의 사용할 일이 없음대부분 @Eager를 사용

@Lazy적용시

@Component
@Lazy
class ClassB {

    private ClassA classA;

    public ClassB(ClassA classA) {
        System.out.println("Some Initialization logic");
        this.classA = classA;
    }

    public void doSomeThing() {
        System.out.println("do something");
    }
}

@Configuration
@ComponentScan
public class LazyInitializationLauncherApplication {

    public static void main(String[] args) {

        try (var context =
                     new AnnotationConfigApplicationContext
                             (LazyInitializationLauncherApplication.class)) {
//            System.out.println("Initialization of context is competed");
//
//            context.getBean(ClassB.class).doSomeThing();
        }
    }
}
  • 아래처럼 아무런 출력값이 없는 것을 확인할 수 있다.
  • 이제 주석을 제거하고 다시 확인해보자

    해당 객체를 참조하는 순간에 초기화되고, 출력값이 나오는 것을 확인할 수 있다.

@Eager 적용시

@Component
class ClassB {

    private ClassA classA;

    public ClassB(ClassA classA) {
        System.out.println("Some Initialization logic");
        this.classA = classA;
    }

    public void doSomeThing() {
        System.out.println("do something");
    }
}

@Configuration
@ComponentScan
public class LazyInitializationLauncherApplication {

    public static void main(String[] args) {

        try (var context =
                     new AnnotationConfigApplicationContext
                             (LazyInitializationLauncherApplication.class)) {
//            System.out.println("Initialization of context is competed");
//
//            context.getBean(ClassB.class).doSomeThing();
        }
    }
}
  • 따로 @Lazy나 @Eager를 붙이지도,
    해당 객체를 참조하지도 않았음에도 불구하고 자동으로 객체가 생성되는 것을 확인할 수 있다.

이것으로 @Lazy와 @Eager의 차이점에 대해서 알아보았다.
위에서 확인한 것처럼 @Lazy는 실무에서 대부분 사용할 일이 없으므로 특별한 경우가 아니라면 @Eager를 사용하자.

profile
꾸준히 하자!

0개의 댓글