Spring
에서는 객체를 직접 new로 생성하지 않고, Bean으로 등록해 컨테이너(ApplicationContext)
가 생성·관리하도록 합니다.
이로 인해 다양한 이점을 얻을 수 있으며, 아래는 그 대표적인 이유들과 Java 코드 예시입니다.
Spring은 의존성 주입(Dependency Injection, DI)을 통해 개발자가 직접 의존 객체를 생성하지 않아도 자동으로 주입해줍니다.
또한 Spring Boot 2.6
이후부터는 순환 참조를 기본적으로 금지하기 때문에, 애플리케이션 실행 시점에 순환 의존성 오류를 사전에 감지할 수 있습니다.
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
@Repository
public class UserRepository {
// DB 접근 로직
}
Spring Bean의 기본 스코프는 singleton
입니다.
따라서 하나의 객체가 애플리케이션 전체에서 공유되며, 불필요한 객체 생성을 방지합니다.
@Component
public class CacheService {
public CacheService() {
System.out.println("CacheService 생성자 호출됨");
}
}
이 Bean이 여러 곳에서 주입되더라도 생성자는 단 한 번만 호출됩니다.
Spring은 객체 생성 → 초기화 → 사용 → 소멸까지 생명주기를 자동으로 관리합니다.
또한 @PostConstruct
, @PreDestroy
등을 통해 개발자가 직접 초기화/정리 로직을 삽입할 수 있습니다.
@Component
public class Scheduler {
@PostConstruct
public void init() {
System.out.println("스케줄러 초기화 작업");
}
@PreDestroy
public void cleanup() {
System.out.println("스케줄러 종료 전 정리 작업");
}
}
Spring AOP
는 Bean을 프록시로 감싸서 부가 기능(트랜잭션, 로깅 등)을 삽입합니다.
AOP는 Bean으로 등록된 객체에만 적용되므로, Bean 관리가 필수입니다.
@Service
public class TransferService {
@Transactional
public void transfer(String from, String to, BigDecimal amount) {
// 트랜잭션 시작 → 비즈니스 로직 → 커밋 or 롤백
}
}
Spring Boot에서는 테스트 시 @MockBean
을 사용해 실제 Bean 대신 Mock 객체를 주입할 수 있습니다.
덕분에 통합 테스트에서도 특정 Bean만 테스트하거나 가짜로 대체하기 쉽습니다.
@SpringBootTest
public class UserServiceTest {
@MockBean
private UserRepository userRepository;
@Autowired
private UserService userService;
@Test
void testFindUser() {
Mockito.when(userRepository.findById(1L))
.thenReturn(Optional.of(new User("홍길동")));
User user = userService.findUser(1L);
assertEquals("홍길동", user.getName());
}
}
Spring에서는 @Configuration
클래스나 @Bean 등록을 통해 어플리케이션 설정을 한 곳에서 관리할 수 있습니다.
이로 인해 설정 변경 시에도 유지보수가 쉬워집니다.
@Configuration
public class AppConfig {
@Bean
public ObjectMapper objectMapper() {
return new ObjectMapper();
}
}
Spring에서 객체를 Bean
으로 등록하여 관리하면, 생성·의존성 주입·생명주기·트랜잭션 처리·테스트 등에서 다양한 장점을 얻을 수 있습니다.
즉, Bean 관리는 단순한 코드 구조가 아닌, 스프링 아키텍처의 핵심이라고 할 수 있습니다.