2024. 11. 14. 12:22ㆍSpring Framework/Spring IoC
🌱 Spring Bean Management: depends-on, Lazy-initialized Beans, Autowiring
Spring에서는 빈(Bean)의 초기화 순서, 지연 로딩(Lazy Initialization), 자동 주입(Autowiring) 을 통해 효율적인 객체 생성 및 관리 를 수행할 수 있습니다.
이번 정리에서는 이러한 개념들을 명확히 설명하고, 활용 방법을 소개하겠습니다.
1️⃣ Using @DependsOn
: 빈 초기화 순서 제어
🔹 @DependsOn
이란?
- 특정 빈이 생성되기 전에 먼저 초기화해야 할 빈을 지정하는 어노테이션
- 빈 간의 의존성을 명시적으로 정의하여, 초기화 순서를 강제할 수 있음
- 다수의 빈을 순차적으로 초기화 가능
✅ 예제: @DependsOn
을 활용한 빈 초기화 순서 제어
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
@Configuration
public class AppConfig {
@Bean
@DependsOn("manager") // manager 빈이 먼저 초기화된 후 실행
public ExampleBean beanOne() {
ExampleBean exampleBean = new ExampleBean();
exampleBean.setManager(manager());
return exampleBean;
}
@Bean
public ManagerBean manager() {
return new ManagerBean();
}
@Bean
public JdbcAccountDao accountDao() {
return new JdbcAccountDao();
}
@Bean
@DependsOn({"manager", "accountDao"}) // manager, accountDao 빈이 먼저 초기화된 후 실행
public ExampleBean beanOneWithMultipleDependencies() {
ExampleBean exampleBean = new ExampleBean();
exampleBean.setManager(manager());
return exampleBean;
}
}
📌 특징
✅ 빈 간의 초기화 순서를 제어할 수 있음
✅ 데이터베이스 연결, 외부 리소스 로드 등 특정 빈을 먼저 실행해야 할 경우 유용
2️⃣ Using @Lazy
: 빈의 지연 초기화 (Lazy Initialization)
🔹 Lazy Initialization이란?
- 빈이 필요할 때까지 초기화를 지연시키는 방식
- 애플리케이션 실행 속도를 높이고, 불필요한 리소스 사용을 방지
✅ 개별 빈에 대해 Lazy Initialization 적용
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
@Configuration
public class AppConfig {
@Bean
@Lazy // lazyBean은 처음 사용될 때까지 초기화되지 않음
public ExpensiveToCreateBean lazyBean() {
return new ExpensiveToCreateBean();
}
@Bean
public AnotherBean notLazyBean() {
return new AnotherBean(); // 즉시 초기화됨
}
}
✅ 모든 빈을 Lazy Initialization으로 설정
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
@Configuration
@Lazy // 이 클래스 내의 모든 빈을 lazy-initialized로 설정
public class AppConfig {
@Bean
public ExpensiveToCreateBean lazyBean() {
return new ExpensiveToCreateBean();
}
@Bean
public AnotherBean notLazyBean() {
return new AnotherBean();
}
}
📌 특징
✅ 리소스를 많이 사용하는 빈(예: DB 연결, 대형 객체 등)의 초기화를 지연시켜 성능 최적화
✅ 모든 빈을 @Lazy
로 설정하면, 최초 요청이 있을 때만 빈을 생성함
3️⃣ Autowiring: 자동 의존성 주입
🔹 Autowiring이란?
- Spring이 자동으로 의존성을 찾아서 주입하는 기능
@Autowired
,@Qualifier
,@Primary
등을 활용하여 특정 빈을 자동 주입할 수 있음- Spring 컨테이너가 적절한 빈을 찾아 연결하므로, 수동 설정 없이 객체를 주입할 수 있음
✅ Autowiring 방식 4가지
Autowiring 모드 | 설명 |
---|---|
no (기본값) | 자동 주입을 사용하지 않음. 의존성은 명시적으로 정의해야 함. |
byName | 속성 이름과 동일한 이름을 가진 빈을 찾아 주입 |
byType | 속성 타입과 일치하는 빈을 찾아 주입 |
constructor | 생성자의 아규먼트 타입과 일치하는 빈을 주입 |
✅ 1. @Autowired
를 사용한 자동 주입
Spring은 타입을 기준으로 적절한 빈을 찾아 주입합니다.
예제: 생성자 기반 @Autowired
@Component
public class Service {
private final Repository repository;
// 생성자 주입 (권장 방식)
@Autowired
public Service(Repository repository) {
this.repository = repository;
}
public void performAction() {
repository.save();
}
}
예제: 세터 기반 @Autowired
@Component
public class Service {
private Repository repository;
@Autowired
public void setRepository(Repository repository) {
this.repository = repository;
}
}
✅ 2. @Qualifier
를 사용하여 특정 빈 지정
Spring이 같은 타입의 여러 빈을 찾을 경우, 명확히 특정 빈을 지정해야 할 때 사용
@Component("mainRepository")
public class MainRepository implements Repository {
public void save() {
System.out.println("Main Repository: Data saved!");
}
}
@Component("backupRepository")
public class BackupRepository implements Repository {
public void save() {
System.out.println("Backup Repository: Data saved!");
}
}
@Component
public class Service {
private final Repository repository;
@Autowired
public Service(@Qualifier("mainRepository") Repository repository) {
this.repository = repository;
}
}
📌 특징
✅ 같은 타입의 여러 빈이 존재할 때, 특정 빈을 지정하여 주입 가능
✅ @Qualifier
를 사용하지 않으면, 모호성(ambiguity) 오류 발생 가능
✅ 3. @Primary
를 사용하여 기본 빈 지정
- 여러 개의 동일한 타입 빈이 존재할 경우, 디폴트로 선택할 빈을 지정
- 명시적으로
@Qualifier
를 사용하지 않더라도,@Primary
가 있는 빈이 기본적으로 주입됨
@Component
@Primary
public class DefaultRepository implements Repository {
public void save() {
System.out.println("Default Repository: Data saved!");
}
}
@Component
public class AlternativeRepository implements Repository {
public void save() {
System.out.println("Alternative Repository: Data saved!");
}
}
📌 특징
✅ 우선적으로 주입될 빈을 지정 가능
✅ @Qualifier
없이도 디폴트 빈을 자동 선택 가능
4️⃣ 순환 의존성 (Circular Dependency) 문제 해결
🔹 순환 의존성이란?
- A가 B를 필요로 하고, B가 다시 A를 필요로 하는 무한 루프 구조
- Spring이 빈을 생성하는 과정에서 BeanCurrentlyInCreationException 발생
✅ 해결 방법 1: 세터 주입 사용
@Component
public class A {
private B b;
@Autowired
public void setB(B b) {
this.b = b;
}
}
✅ 해결 방법 2: @Lazy
사용
@Component
public class A {
private final B b;
@Autowired
public A(@Lazy B b) {
this.b = b;
}
}
📌 순환 의존성 해결 방법
✅ 세터 주입 사용
✅ @Lazy
를 활용하여 객체 생성 시점을 지연
🎯 Summary (요약)
🔹 @DependsOn
→ 빈 초기화 순서 강제 설정 가능
🔹 @Lazy
→ 리소스를 많이 사용하는 빈을 지연 로딩하여 성능 최적화
🔹 @Autowired
+ @Qualifier
+ @Primary
→ 빈 자동 주입 및 충돌 해결 가능
🔹 순환 의존성 해결 → 세터 주입 또는 @Lazy
활용
🚀 이러한 기술을 적절히 활용하면 유지보수성이 높은 확장 가능한 애플리케이션을 개발할 수 있습니다! 🎯
'Spring Framework > Spring IoC' 카테고리의 다른 글
Bean Scopes (0) | 2024.11.14 |
---|---|
Method Injection (0) | 2024.11.14 |
Dependencies (0) | 2024.11.14 |
Dependency Injection (0) | 2024.06.11 |
Bean Overview (0) | 2024.06.11 |