기본값은 true이며, 이 경우 스프링이 @Configuration 클래스를 CGLIB 프록시로 감싸서 메서드 호출을 가로채고, 항상 싱글톤 빈을 반환합니다.

하지만 false로 설정하면 프록시를 사용하지 않으며, 각 @Bean 메서드가 직접 호출되어 빈을 생성합니다. 다음과 같이 예제를 통해 상세 내용을 갈음하고자 한다.

// helloService()와 worldService()는 서로 의존하지 않기 때문에 proxyBeanMethods = false로 해도 문제 없습니다.
// 이럴 땐 성능 면에서 약간 이득을 볼 수 있습니다. (프록시 미사용)
@Configuration(proxyBeanMethods = false)
public class SimpleConfiguration {

    @Bean
    public HelloService helloService() {
        return new HelloService();
    }

    @Bean
    public WorldService worldService() {
        return new WorldService();
    }
}

// proxyBeanMethods = true 인 경우
// proxyBeanMethods = true라서 repository()가 여러 번 호출되어도 동일한 인스턴스를 리턴함
// Spring이 내부적으로 프록시를 사용해서 해당 메서드 호출을 컨테이너 호출로 변환
@Configuration
public class ServiceConfiguration {

    @Bean
    public Repository repository() {
        return new Repository();
    }

    @Bean
    public Service service() {
        return new Service(repository()); // 프록시로 가로채서 싱글톤 보장됨
    }
}

// 아래와 같이 하면 repository()가 직접 호출되어 다른 인스턴스가 생성됩니다.
// Service는 실제로 스프링 빈이 아닌, 새롭게 만들어진 Repository를 참조합니다.
@Configuration(proxyBeanMethods = false)
public class WrongConfiguration {

    @Bean
    public Repository repository() {
        return new Repository();
    }

    @Bean
    public Service service() {
        return new Service(repository()); // 직접 호출되므로 새 인스턴스!
    }
}

// 이 방식은 가장 안정적이고, 성능까지 고려한 현대적인 스프링 방식입니다.
// 생성자 주입이나 메서드 인자 주입을 적극적으로 활용하세요.
@Configuration(proxyBeanMethods = false)
public class SafeConfiguration {

    @Bean
    public Repository repository() {
        return new Repository();
    }

    @Bean
    public Service service(Repository repository) {
        return new Service(repository); // 스프링이 주입하므로 안전
    }
}
반응형

+ Recent posts