Spring 빈(Bean)
### **Spring에서 빈(Bean)이란?**
**Spring Bean(스프링 빈)**은 **Spring IoC 컨테이너(Bean Container)**가 관리하는 **객체**를 의미합니다.\
즉, Spring이 자동으로 생성하고 관리하는 인스턴스를 **Bean**이라고 부릅니다.
* * * * *
**1\. 빈(Bean)이 왜 필요할까?**
------------------------
자바에서는 객체를 사용할 때 `new` 키워드를 사용하여 직접 생성하는 경우가 많습니다.
```
public class UserService {
private UserRepository userRepository = new UserRepository();
}
```
- 하지만 위처럼 직접 객체를 생성하면 **코드가 하드코딩**되고,
- 유지보수가 어렵고, **객체 간의 결합도가 높아지는 문제**가 발생합니다.
✅ **해결책**: Spring의 **빈 컨테이너**를 사용하여 객체를 자동으로 관리!\
Spring에서는 객체를 직접 생성하지 않고, **Spring이 자동으로 생성하고 주입**하도록 설계할 수 있습니다.
```
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) { // 빈을 자동 주입
this.userRepository = userRepository;
}
}
```
➡ **객체 생성을 Spring이 관리하므로, 유지보수가 쉬워지고 결합도가 낮아짐.**
* * * * *
**2\. 빈(Bean)을 만드는 방법**
-----------------------
Spring에서 빈을 등록하는 방법은 여러 가지가 있습니다.
### **(1) @Component 계열 어노테이션 사용**
Spring은 특정 어노테이션이 붙은 클래스들을 자동으로 **Spring Bean으로 등록**합니다.
| 어노테이션 | 역할 |
| --- | --- |
| `@Component` | 기본적인 빈 등록 (부모 어노테이션) |
| `@Service` | **서비스 계층**을 나타내는 빈 등록 |
| `@Repository` | **데이터 접근 계층**을 나타내는 빈 등록 |
| `@Controller` | **웹 컨트롤러**를 나타내는 빈 등록 |
#### **예제: @Service 사용**
```
@Service
public class UserService {
public String getUserName() {
return "John Doe";
}
}
```
Spring이 `UserService` 클래스를 **자동으로 Bean으로 등록**하여 관리합니다.
* * * * *
### **(2) @Bean 어노테이션 사용**
직접 `@Bean`을 사용하여 빈을 등록할 수도 있습니다.
#### **예제: @Configuration과 @Bean 사용**
```
@Configuration
public class AppConfig {
@Bean
public UserService userService() {
return new UserService();
}
}
```
- `@Configuration` 클래스 내부에서 `@Bean`을 사용하면 해당 객체가 빈으로 등록됩니다.
* * * * *
### **(3) XML을 사용한 빈 등록 (구식)**
Spring 2.x 이전에는 XML 설정을 많이 사용했지만, 지금은 어노테이션 기반이 더 일반적입니다.
#### **예제: XML 설정**
```
<bean id="userService" class="com.example.UserService"/>
```
이제는 거의 사용되지 않으며, XML 없이 어노테이션 기반으로 설정하는 것이 일반적입니다.
* * * * *
**3\. 빈(Bean)의 사용 (의존성 주입)**
----------------------------
### **빈을 주입하는 방법**
빈을 사용하려면, **의존성 주입(Dependency Injection, DI)**을 통해 가져와야 합니다.
### **(1) @Autowired 사용**
Spring이 `@Autowired`를 통해 빈을 자동으로 주입해 줍니다.
```
@Service
public class UserService {
@Autowired
private UserRepository userRepository; // UserRepository 빈 자동 주입
}
```
✅ `@Autowired`를 사용하면 **Spring이 자동으로 빈을 찾아서 주입**해 줍니다.
* * * * *
### **(2) 생성자 주입 (권장)**
Spring에서는 생성자를 이용한 의존성 주입을 **더 권장**합니다.
```
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) { // 생성자를 통한 빈 주입
this.userRepository = userRepository;
}
}
```
✅ **장점**:
- `@Autowired` 없이도 **빈을 자동으로 주입**.
- **테스트가 용이**하고, **불변성 유지**.
* * * * *
**4\. 빈(Bean) 관리의 핵심**
----------------------
### **📌 Spring이 빈을 관리하는 원리**
1. **객체 생성**: `@Component`, `@Service`, `@Repository` 등의 어노테이션이 붙은 클래스를 스캔하여 **Spring이 빈을 자동 생성**.
2. **의존성 주입(DI)**: `@Autowired` 또는 생성자를 통해 **필요한 빈을 자동으로 연결**.
3. **싱글톤(Singleton) 기본 설정**: 기본적으로 모든 빈은 **애플리케이션 전체에서 하나만 존재**하여 공유됨.
4. **필요할 때 빈을 가져와 사용**: `@Autowired` 또는 `ApplicationContext`를 통해 가져올 수 있음.
* * * * *
**5\. 빈(Bean) 관련 추가 개념**
------------------------
### **(1) 빈의 라이프사이클**
빈은 생성 → 초기화 → 사용 → 소멸 단계를 거칩니다.
```
@Component
public class MyBean {
@PostConstruct
public void init() {
System.out.println("빈 초기화");
}
@PreDestroy
public void destroy() {
System.out.println("빈 소멸");
}
}
```
✅ `@PostConstruct`: 빈이 생성된 후 실행.\
✅ `@PreDestroy`: 빈이 소멸되기 전에 실행.
* * * * *
### **(2) 빈의 스코프(Scope)**
기본적으로 Spring의 빈은 **싱글톤(Singleton)**이지만, 필요에 따라 다르게 설정할 수도 있습니다.
| 스코프 | 설명 |
| --- | --- |
| `singleton` | (기본) **애플리케이션 내에서 한 개만 존재**하는 빈 |
| `prototype` | 매번 **새로운 객체를 생성** |
| `request` | 웹 요청(Request)마다 새로운 빈 생성 |
| `session` | 사용자 세션마다 새로운 빈 생성 |
#### **예제: Prototype 스코프 설정**
```
@Scope("prototype")
@Component
public class PrototypeBean {}
```
➡ **이제 `PrototypeBean`은 매번 새로운 인스턴스가 생성됨.**
* * * * *
**6\. 결론: 스프링 빈(Bean)이란?**
--------------------------
- **Spring이 생성하고 관리하는 객체**를 **Bean(빈)**이라고 함.
- 빈은 `@Component`, `@Service`, `@Repository`, `@Controller` 등을 통해 자동 등록됨.
- 빈을 사용하려면 **의존성 주입(DI)**이 필요하며, `@Autowired` 또는 **생성자 주입**을 사용함.
- 빈은 기본적으로 **싱글톤**이며, 필요에 따라 스코프를 변경할 수 있음.
* * * * *
**7\. 정리**
----------
✅ **빈(Bean)은 Spring이 관리하는 객체**\
✅ **빈을 자동 등록하려면 `@Component`, `@Service`, `@Repository` 사용**\
✅ **빈을 주입하려면 `@Autowired` 또는 생성자 주입을 사용**\
✅ **기본적으로 모든 빈은 싱글톤** (필요하면 스코프 변경 가능)
* * * * *
# 빈 주입
### **빈(Bean) 주입이란?**
Spring에서 **"빈을 주입한다"**는 말은 **객체(인스턴스)를 직접 생성하는 대신, Spring이 자동으로 만들어서 필요한 곳에 넣어주는 것**을 의미합니다.\
이를 **의존성 주입(Dependency Injection, DI)**이라고도 합니다.
* * * * *
**1\. 직접 객체를 생성하는 방식 vs 빈 주입 방식**
---------------------------------
### ❌ **(1) 직접 객체를 생성하는 경우 (`new` 키워드 사용)**
```
public class UserService {
private UserRepository userRepository = new UserRepository(); // 직접 객체 생성
}
```
- `new UserRepository()`를 사용해서 직접 객체를 만듦.
- 만약 `UserRepository`의 생성자가 바뀌거나, 다른 클래스를 사용해야 하면 **모든 코드를 수정해야 함**.
- `UserService`가 `UserRepository`에 강하게 결합됨 → **유지보수 어려움**.
* * * * *
### ✅ **(2) 빈을 주입하는 경우 (Spring이 관리)**
```
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) { // Spring이 자동 주입
this.userRepository = userRepository;
}
}
```
- `new`를 사용하지 않음.
- `UserRepository` 객체는 **Spring이 알아서 생성하고 주입**해 줌.
- **유지보수가 쉬워지고, 테스트도 간편해짐**.
* * * * *
**2\. 빈 주입(의존성 주입, DI)의 개념**
----------------------------
**💡 객체를 직접 생성하지 않고, Spring이 대신 만들어서 넣어주는 것.**
- 개발자가 `new`를 사용하지 않고도 객체를 사용할 수 있음.
- Spring이 객체를 **관리**하면서, 필요할 때만 생성하고 공유할 수 있음.
* * * * *
**3\. 빈을 주입하는 방법 3가지**
----------------------
Spring에서 빈을 주입하는 방법은 크게 **3가지**가 있습니다.
* * * * *
### **(1) @Autowired (필드 주입)**
Spring이 자동으로 빈을 찾아서 **필드에 주입**해 줍니다.
```
@Service
public class UserService {
@Autowired
private UserRepository userRepository; // Spring이 자동으로 주입
}
```
✅ **장점**: 간단하게 사용할 수 있음.\
❌ **단점**: **테스트하기 어렵고, 의존성이 명확하지 않음** → 생성자 주입이 더 권장됨.
* * * * *
### **(2) 생성자 주입 (권장)**
객체를 주입할 때 **생성자를 통해 주입**하는 방식입니다.
```
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) { // 생성자 주입
this.userRepository = userRepository;
}
}
```
✅ **장점**:
- `@Autowired` 없이도 Spring이 자동으로 주입해 줌.
- **불변성 유지** (`final` 사용 가능).
- **테스트하기 쉬움** (필요하면 다른 객체로 교체 가능). ❌ **단점**: 코드가 조금 길어질 수 있음.
* * * * *
### **(3) @Bean을 사용한 수동 주입**
개발자가 직접 빈을 생성하여 등록하는 방식.
```
@Configuration
public class AppConfig {
@Bean
public UserService userService(UserRepository userRepository) {
return new UserService(userRepository);
}
}
```
✅ **장점**:
- Spring이 자동으로 관리하지 않는 객체도 직접 주입 가능. ❌ **단점**:
- 일반적인 서비스에서는 잘 사용되지 않고, 특수한 경우에만 필요.
* * * * *
**4\. 빈 주입의 장점**
----------------
Spring에서 빈을 주입하는 방식(DI)을 사용하면 다음과 같은 이점이 있습니다.
✅ **1) 유지보수 용이**
- `new`로 직접 객체를 만들지 않으므로, 코드 변경이 적음.
- 예를 들어, `UserRepository`를 `NewUserRepository`로 변경해도 **코드 수정 없이 주입할 객체만 변경하면 됨**.
✅ **2) 객체 재사용 가능 (싱글톤)**
- Spring은 기본적으로 **하나의 객체(빈)를 공유(싱글톤)하여 메모리 절약**.
- 필요하면 여러 개의 인스턴스를 생성하도록 설정도 가능.
✅ **3) 테스트하기 쉬움**
- `new`를 사용하면 객체가 고정되지만, **DI를 사용하면 테스트할 때 원하는 객체를 주입해서 테스트 가능**.
✅ **4) 코드가 간결하고 읽기 쉬움**
- 객체 생성을 직접 관리하지 않아도 되므로, 코드가 깔끔해짐.
* * * * *
**5\. 예제: 빈을 직접 주입하는 것과 비교**
----------------------------
### **(1) 직접 객체 생성 방식**
```
public class UserService {
private UserRepository userRepository = new UserRepository();
}
```
- `UserRepository`를 변경하려면 **모든 코드 수정** 필요.
* * * * *
### **(2) Spring의 빈 주입 방식**
```
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
```
- `UserRepository`가 변경되더라도, **Spring이 알아서 변경된 객체를 주입**.
* * * * *
**6\. 결론**
----------
- **빈(Bean)** = **Spring이 관리하는 객체**.
- **빈을 주입한다** = **Spring이 객체를 생성하고 필요한 곳에 자동으로 넣어줌**.
- **빈 주입(의존성 주입, DI)**을 사용하면 **코드가 깔끔해지고 유지보수하기 쉬워짐**.
댓글
댓글 쓰기