Bean
title: 2026-03-16 author: 강병호 (이름) date: 2026-03-16 (날짜) category: TIL/강병호/2026/03 (파일 경로 : TIL/{이름}/{연}/{월}) layout: post (자유) —
Spring 프레임워크의 핵심은 제어의 역전(Inversion of Control, IoC)입니다. 개발자가 직접 객체를 생성하고 관리하는 대신, Spring 컨테이너에 그 역할을 위임하는 방식입니다. 이때 컨테이너가 관리하는 객체를 Bean이라 부릅니다. 객체를 Bean으로 관리할 때 얻는 기술적 이점들을 정리했습니다.
1. 의존성 관리의 자동화 (Dependency Injection)
Bean으로 등록된 객체는 Spring 컨테이너가 필요한 의존성을 자동으로 주입해 줍니다. 개발자가 직접 객체를 생성하고 수동으로 연결할 필요가 없어 코드의 결합도가 낮아집니다. 또한 컨테이너가 빌드 시점에 순환 의존성을 감지하여 설계 결함을 조기에 발견할 수 있습니다.
@Service
class OrderService(
private val productRepository: ProductRepository, // 자동 주입
private val paymentGateway: PaymentGateway // 자동 주입
)
2. 싱글톤 패턴을 통한 자원 효율성
Spring은 기본적으로 Bean을 싱글톤(Singleton)으로 관리합니다. 애플리케이션 전반에서 하나의 공유 인스턴스만 사용하므로 메모리 사용을 최적화하고 불필요한 객체 생성 비용을 줄입니다.
// 아래 두 서비스에 주입되는 userRepository는 동일한 인스턴스입니다.
@Service
class UserService(private val userRepository: UserRepository)
@Service
class AuthService(private val userRepository: UserRepository)
3. 정교한 생명주기 관리 (Lifecycle Callback)
Spring 컨테이너는 Bean의 생성부터 소멸까지의 전 과정을 제어합니다. 이를 통해 리소스 할당이나 해제와 같은 작업을 체계적으로 처리할 수 있습니다.
@Component
class DatabaseConnection {
@PostConstruct
fun initialize() {
// 커넥션 풀 확보 등 초기화 로직
}
@PreDestroy
fun cleanup() {
// 리소스 정리와 종료 로직
}
}
4. AOP(관점 지향 프로그래밍) 지원
Bean으로 관리되는 객체는 Spring의 프록시(Proxy) 메커니즘을 통해 트랜잭션 처리, 로깅, 보안 등의 공통 기능을 쉽게 적용받을 수 있습니다. 비즈니스 로직과 부가 기능을 깔끔하게 분리할 수 있다는 장점이 있습니다.
@Service
class TransferService(private val accountRepository: AccountRepository) {
@Transactional // AOP를 통해 트랜잭션 경계 설정
fun transferMoney(from: String, to: String, amount: BigDecimal) {
// 송금 로직
}
}
5. 테스트 용이성 (Testability)
Bean 구조는 컴포넌트 간의 결합을 인터페이스 수준으로 유지하기 좋습니다. 테스트 환경에서 실제 구현체 대신 모의 객체(Mock)를 주입하기 편리하므로 단위 테스트의 독립성을 보장합니다.
@SpringBootTest
class UserServiceTest {
@MockBean
lateinit var userRepository: UserRepository
@Autowired
lateinit var userService: UserService
@Test
fun testGetUser() {
val userId = 1L
whenever(userRepository.findById(userId)).thenReturn(User(userId, "Test User"))
val result = userService.getUser(userId)
assertEquals("Test User", result.name)
}
}
6. 설정의 중앙 집중화
애플리케이션의 구성 요소를 Bean으로 정의하면 설정을 한 곳에서 관리할 수 있습니다. 이는 시스템의 구조를 파악하기 쉽게 만들고 환경 변화에 유연하게 대처할 수 있도록 돕습니다.
@Configuration
class AppConfig {
@Bean
fun dataSource(): DataSource {
return HikariDataSource().apply {
jdbcUrl = "jdbc:postgresql://localhost:5432/mydb"
username = "user"
password = "password"
maximumPoolSize = 10
}
}
}