Java의 @Bean 어노테이션에 대한 상세 설명
Spring 프레임워크는 자바 애플리케이션 개발 시 의존성 주입(Dependency Injection, DI)을 지원하는 강력한 기능을 제공한다. 이 중 @Bean 어노테이션은 스프링의 빈(Bean)을 수동으로 등록하는 데 사용된다. @Component, @Service, @Repository 등의 자동 감지(Annotation-based Component Scanning) 방식과 달리, 개발자가 직접 특정 객체를 빈으로 등록할 때 유용하다. 이 글에서는 @Bean 어노테이션의 동작 방식, 활용법, 주의할 점 등을 자세히 살펴본다.
1. @Bean 어노테이션이란?
@Bean 어노테이션은 스프링 컨테이너에 특정 메서드가 반환하는 객체를 빈으로 등록하도록 하는 역할을 한다. 이를 통해 개발자는 명시적으로 빈을 정의하고 제어할 수 있다.
기본적인 사용법
아래는 @Bean 어노테이션을 사용하는 가장 기본적인 예제다.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyService();
}
}
위 코드에서 @Configuration은 해당 클래스가 설정(Configuration) 클래스임을 나타내며, @Bean 어노테이션이 붙은 myService 메서드는 스프링 컨테이너에 MyService 객체를 빈으로 등록한다.
2. @Bean vs @Component 차이점
Spring에서 빈을 등록하는 방법은 크게 두 가지로 나눌 수 있다.
등록 방식 어노테이션 설명
자동 등록 | @Component, @Service, @Repository | 클래스 수준에서 선언하면 Spring이 자동으로 감지하여 빈으로 등록 |
수동 등록 | @Bean | 개발자가 직접 설정 클래스를 만들고, 메서드에서 객체를 반환하여 등록 |
자동 등록 (@Component 계열)
- @Component, @Service, @Repository를 사용하면 Spring이 컴포넌트 스캔을 통해 자동으로 빈을 등록한다.
- 기본적으로 패키지 내에서 클래스를 자동으로 탐색하기 때문에 설정이 간편하다.
수동 등록 (@Bean)
- 특정 라이브러리의 클래스를 빈으로 등록할 때 유용하다.
- 객체 생성 과정에서 추가적인 설정이 필요한 경우 사용할 수 있다.
- 코드의 가독성과 유지보수성을 높이는 데 도움을 줄 수 있다.
예제:
import org.springframework.stereotype.Service;
@Service
public class MyService {
public void doSomething() {
System.out.println("Service is doing something");
}
}
위 코드처럼 @Service를 사용하면 Spring이 자동으로 빈을 등록하지만, @Bean을 사용하면 보다 세밀한 제어가 가능하다.
3. @Bean의 주요 특징 및 동작 방식
(1) 메서드 이름이 빈의 이름이 됨
@Bean 어노테이션을 사용하면 해당 메서드의 이름이 스프링 빈의 기본 이름이 된다.
@Bean
public MyService myService() {
return new MyService();
}
이 경우, 빈의 이름은 "myService"가 된다. 하지만 명시적으로 이름을 지정할 수도 있다.
@Bean(name = "customService")
public MyService myService() {
return new MyService();
}
이렇게 하면 빈의 이름이 "customService"로 변경된다.
(2) 싱글턴(Singleton) 범위가 기본값
스프링의 빈은 기본적으로 싱글턴(Singleton) 으로 등록된다. 즉, @Bean 어노테이션을 통해 생성된 객체는 하나의 인스턴스만 유지된다.
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyService();
}
}
위와 같이 myService() 메서드가 여러 번 호출되더라도, 항상 같은 인스턴스를 반환한다.
싱글턴이 아닌 매번 새로운 인스턴스를 생성하려면 @Scope 어노테이션을 활용할 수 있다.
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Bean
@Scope("prototype")
public MyService myService() {
return new MyService();
}
이렇게 하면 myService()가 호출될 때마다 새로운 객체가 생성된다.
4. @Bean을 활용한 의존성 주입
일반적으로 @Bean을 사용하여 다른 빈을 주입할 수 있다.
@Configuration
public class AppConfig {
@Bean
public MyRepository myRepository() {
return new MyRepository();
}
@Bean
public MyService myService(MyRepository myRepository) {
return new MyService(myRepository);
}
}
위 코드에서 myService는 myRepository를 생성자의 인자로 받아 의존성을 해결한다.
5. Factory Method 패턴 활용
@Bean을 활용하여 Factory Method 패턴을 구현할 수도 있다.
@Configuration
public class FactoryConfig {
@Bean
public CarFactory carFactory() {
return new CarFactory();
}
@Bean
public Car car(CarFactory carFactory) {
return carFactory.createCar();
}
}
위 코드에서 carFactory 빈을 생성한 뒤, 이를 이용해 car 빈을 생성한다.
6. 외부 라이브러리 객체 등록
Spring이 관리하지 않는 외부 라이브러리의 객체도 @Bean을 통해 등록할 수 있다.
import org.apache.commons.dbcp2.BasicDataSource;
import javax.sql.DataSource;
@Configuration
public class DataSourceConfig {
@Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setUrl("jdbc:mysql://localhost:3306/mydb");
dataSource.setUsername("user");
dataSource.setPassword("password");
return dataSource;
}
}
이제 DataSource 빈이 등록되었으므로, 다른 클래스에서 주입하여 사용할 수 있다.
7. @Bean의 초기화 및 소멸 메서드 지정
스프링 빈은 생성된 이후 초기화 작업을 수행하거나, 애플리케이션 종료 시 자원을 해제할 수 있다.
@Bean(initMethod = "init", destroyMethod = "cleanup")
public MyService myService() {
return new MyService();
}
여기서 init()과 cleanup()은 각각 초기화 및 종료 시 호출될 메서드이다.
public class MyService {
public void init() {
System.out.println("Initializing MyService");
}
public void cleanup() {
System.out.println("Cleaning up MyService");
}
}
'게으른 개발자의 끄적거림' 카테고리의 다른 글
HTTP 401error란? (0) | 2025.04.10 |
---|---|
Java DB연결 방법 완벽 정리 (0) | 2025.03.20 |
RPA란? (개념, 활용 사례 등) (1) | 2025.03.19 |
RPA 주요 Activity(기능) 완벽 정리 (0) | 2025.03.17 |
Spring @Component @Bean 완벽 정리 (0) | 2025.03.15 |