스프링

스프링 - 스프링

개발자 포비 2024. 12. 9. 17:48

스프링 빈(Spring Bean)의 이해

빈이란?

스프링 IoC 컨테이너로 관리되는 객체를 의미합니다.

빈 등록 방법

  1. 컴포넌트 스캔을 통한 자동 등록

    @Component
    public class UserService {
     // ...
    }
  2. 설정 클래스를 통한 수동 등록

    @Configuration
    public class AppConfig {
     @Bean
     public UserService userService() {
         return new UserService();
     }
    }

빈과 의존성 주입

  • IoC 컨테이너에서 관리되는 빈을 통해 해당 객체가 필요한 곳에 자동으로 의존성을 주입합니다
  • 별도의 주입 과정을 거치지 않아도 되므로 의존성 관리가 자동화됩니다

의존성 주입 방법

// 1. 생성자 주입 (권장)
@Service
public class UserService {
    private final UserRepository userRepository;

    @Autowired  // 생성자가 하나면 생략 가능
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}

// 2. 필드 주입 (권장하지 않음)
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
}

// 3. 수정자(Setter) 주입
@Service
public class UserService {
    private UserRepository userRepository;

    @Autowired
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}

빈과 싱글턴

  • 빈은 싱글턴 객체로 관리됩니다
  • 일반적인 싱글턴 패턴 사용 시 발생하는 상속 불가 등의 제약사항을 피할 수 있습니다
  • IoC에 의해 빈으로 등록된 객체는 다음과 같은 생명주기로 관리됩니다:
객체 생성 + property 설정 → 의존 설정 → 초기화 → 사용 → 소멸

빈 생명주기 콜백

@Component
public class ExampleBean implements InitializingBean, DisposableBean {
    @PostConstruct
    public void init() {
        // 초기화 로직
    }

    @PreDestroy
    public void cleanup() {
        // 종료 전 정리 로직
    }
}

빈 설정 시 주의사항

싱글턴 특성과 상태 관리

// 잘못된 예
@Service
public class CounterService {
    private int count = 0;  // 상태를 가지는 필드

    public void increment() {
        count++;  // 멀티스레드 환경에서 문제 발생
    }
}

// 올바른 예
@Service
public class CounterService {
    private final AtomicInteger count = new AtomicInteger(0);  // 스레드 안전한 객체 사용

    public void increment() {
        count.incrementAndGet();
    }
}

스코프 관리

@Component
@Scope("prototype")  // 매번 새로운 인스턴스 생성
public class PrototypeBean {
    // ...
}

@Component
@SessionScope  // HTTP 세션당 하나의 인스턴스
public class UserPreferences {
    // ...
}

의존성 주입 시 주의점

// 동일 인터페이스를 구현하는 여러 빈이 있는 경우
@Primary
@Repository
public class JpaUserRepository implements UserRepository {
    // 기본으로 주입될 구현체
}

@Repository
@Qualifier("memory")
public class MemoryUserRepository implements UserRepository {
    // 특별히 지정할 때만 사용할 구현체
}

결론

스프링 빈을 통해 프로젝트에서 사용되는 객체들을 효율적으로 관리하고 사용할 수 있습니다. IoC 컨테이너의 자동화된 객체 관리를 통해 개발자는 비즈니스 로직에 더 집중할 수 있게 됩니다.