티스토리 뷰

Java/spring

spring bean lite mode

LichKing 2019. 8. 3. 19:14

spring bean 설정시 lite mode 라는게 있어서 찾아보고, 그에대해 정리해보려한다.

일단 lite mode 는 java 설정에서만 사용할 수 있다. 보통의 java 설정파일을 알아보자.

@Configuration
public class BeanConfig1 {
    @Bean
    public ObjectMapper objectMapperBean() {
        return new ObjectMapper();
    }
}

평소에 많이 사용하는 java 설정 내용이다. @Bean 애노테이션을 이용해 spring bean 을 생성한다. 그리고 이 java 클래스가 설정 클래스임을 나타내기위해 @Configuration 애노테이션을 사용한다. @Configuration 애노테이션은 설정 클래스임을 나타내며 그 자신도 spring bean 으로 등록된다.

lite mode 로 bean 을 생성하기위해선 @Configuration 애노테이션만 변경해주면 된다.

@Component
public class BeanConfig2 {
    @Bean
    public ObjectMapper objectMapperLiteBean() {
        return new ObjectMapper();
    }
}

@Configuration 애노테이션을 @Component 로 변경했다. 이렇게하면 objectMapperLiteBean 은 lite mode 로 spring bean 을 생성한다. 정확히 표현하면 lite mode 로 spring bean 을 생성한다기보다 objectMapperLiteBean 메서드가 lite mode 로 작동한다. 지금 표현이 헷갈릴 수 있는데 bean 이 아니라 메서드라고 표현한거에 집중하자. bean 생성은 똑같이 된다. 다만 메서드를 직접 호출할때의 방식이 달라지는 것뿐이다.

@Configuration
public class BeanConfig1 {
    @Bean
    public ObjectMapper objectMapperBean() {
        return new ObjectMapper();
    }

    @Bean
    public ObjectMapper anyObjectMapperBean() {
        return objectMapperBean();
    }
}

spring bean 을 하나 더 생성한다. 새로 추가한 메서드는 기존에 존재하던 메서드를 호출하고있다. 이렇게 메서드를 직접 호출할 경우 설정 클래스는 ObjectMapper 객체를 하나 더 생성해서 리턴하는것이 아니라 내부에 이미 만들어놓은 spring bean 을 리턴한다. 결과적으로 진짜로 ObjectMapper 객체를 생성하는 objectMapperBean() 메서드는 저렇게 하더라도 1번만 실행된다는 말이다.

@Component
public class BeanConfig2 {
    @Bean
    public ObjectMapper objectMapperLiteBean() {
        return new ObjectMapper();
    }

    @Bean
    public ObjectMapper anyobjectMapperLiteBean() {
        return objectMapperLiteBean();
    }
}

@Component 로 설정한 설정 클래스에도 똑같은 내용의 메서드를 추가했다. 이 경우엔 anyobjectMapperLiteBean() 를 이용해서 objectMapperLiteBean() 를 호출하면 진짜 메서드를 호출하여 ObjectMapper 객체를 하나 더 만들게 된다. 즉 저렇게 설정할경우 ObjectMapper 객체는 총 2개가 생성되는 것이다.

그 이유는 무엇일까?

@Configuration 을 이용해 설정 클래스를 만들면 CGLIB를 이용한 프록시 객체를 동적으로 생성하게된다. 그리고 동적으로 생성된 프록시 객체는 프록시 답게 메서드에 대한 요청을 가로채게된다. 하지만 @Component 로 설정 클래스를 만들면 이 클래스는 프록시 객체가 아니라 순수하게 객체로 생성된다. 그렇다보니 메서드를 호출하게될 경우 가로채지않고 순수하게 메서드가 처리되는 것이다.

BeanConfig1$$EnhancerBySpringCGLIB$$ae2d5339@6b44435b
BeanConfig2@2ccca26f

(BeanConfig1 과 BeanConfig2 의 내용을 출력한 결과, BeanConfig1 은 CGLIB 프록시 클래스인걸 확인할 수 있다.)

다만 @Component 설정 클래스 내에서도 메서드 호출이 아니라 파라미터 주입을 통해 주입받는 경우엔 @Configuration 과 마찬가지로 기존 spring bean 이 주입된다. lite mode 는 이정도 뿐이다.

설정 클래스 내에서 bean 주입이 필요한 경우 (진짜 그게 필요해서 의도한게 아니라면) 메서드 호출이 아니라 파라미터 주입을 받고 설정 클래스들은 @Component 로 선언하면 설정 클래스들의 프록시 객체를 만들지 않아도 되므로 조금 더 가벼워질것같기는 하다.

하지만 보통의 경우 서버를 띄울때만 한번 생성하면 되므로 성능을 위해 lite mode 를 사용할일은 거의 없을것 같다. 오히려 lite mode 로 사용함으로써 이를 잘 모르는 개발자로 인해 의도치않은 상황을 만날 케이스만 더 늘어나지않을까 싶다.

댓글
댓글쓰기 폼