- static
- 데이터베이스
- spring security 6
- java
- springboot
- spring
- select
- hibernate
- spring mvc
- jpa
- SSL
- spring boot
- Docker
- 스프링부트
- 스프링
- 1차원 배열
- mysql
- 프로그래머스
- join
- string
- sql
- Django
- DI
- 자바
- PYTHON
- nginx
- ORM
- @transactional
- 문자열
- AWS
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
개발하는 자몽
AnnotationConfigApplicationContext와 static class 본문
인프런 김영한 님의 스프링 인강을 보며 코딩을 하다가 궁금한 점이 생겨서 정리해본다.
public class ApplicationContextSameBeanFindTest {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SameBeanConfig.class);
...
@Configuration
static class SameBeanConfig {
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
@Bean
public MemberRepository memberRepository2() {
return new MemoryMemberRepository();
}
}
}
new AnnotationConfigApplicationConxt(SameBeanConfig.class)에서 괄호 안에 들어가는 인자는 설정정보를 담은 클래스이다. SameBeanConfig 클래스는 테스트를 위한 설정정보(의존관계)를 담고 있으며 ApplicationContextSameBeanFindTest 클래스의 inner static 클래스(static nested class)로 존재한다.
ApplicationContextSameBeanFindTest 클래스에서만 사용하기 위해서 내부 클래스로 만들었다고 하지만 내부 클래스에는 instance 클래스와 static 클래스가 있다. 나는 이 중에서 왜 static으로 선언했는지 궁금했다.
그래서 일단 static 키워드를 없애고 실행해봤다.
public class ApplicationContextSameBeanFindTest {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SameBeanConfig.class);
...
@Configuration
class SameBeanConfig {
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
@Bean
public MemberRepository memberRepository2() {
return new MemoryMemberRepository();
}
}
}
위 코드대로 실행하는 경우 아래와 같은 오류가 발생한다.
org.springframework.beans.factory.UnsatisfiedDependencyException
어떤 에러인지 찾아보니 빈 의존관계 주입 실패로 인해 발생한다고 한다.
내 추측으로는 instance inner 클래스로 선언하는 경우 AnnotationConfigApplicationContext 객체가 생성되는 시기보다 늦게 생성되어서 빈 의존관계 주입 시 에러가 나는 게 아닌가 싶다. static 키워드가 붙은 경우 클래스가 메모리에 올라갈 때 생기므로 ac 인스턴스가 생성되는 시기보다 먼저 생성되기 때문이다. (instance는 인스턴스가 생성될 때다)
추측이 맞는지 확인할 겸 인프런에 질문을 올렸다.
David님이 답변으로 걸어주신 링크에 들어가서 확인해보니, 이전에 블로그 포스팅으로 올린 글과 연관이 있었다. (생각해보면 당연한 건데 까먹다니..)
static inner 클래스는 outer 클래스에 선언되어있지만 outer 클래스의 객체 생성과는 별개로 만들어진다. 즉, 독립적으로 사용된다. 하지만 instance inner 클래스는 outer 클래스에 선언되고 종속된다. 따라서 outer 클래스의 객체를 통해야 inner 클래스에 접근할 수 있다.
SUMMERY
SameBeanConfig 클래스가 static 키워드 없이(instance inner 클래스) 선언 되었다면 outer 클래스인 ApplicationContextSameBeanFindTest가 생성되어야 사용할 수 있다. 하지만 outer 클래스 내에서는 inner 클래스가 생성되기도 전에 스프링 컨테이너에서 SameBeanConfig Bean이 있는지 찾으려고 한다. 당연히 스프링에서는 그런 Bean은 없다고 한다. (의존관계 주입 실패)
static 키워드를 붙이면 outer 클래스와 별개로 SameBeanConfig 클래스가 생성되고 빈으로 등록된다. 자연히 outer 클래스에서는 스프링 컨테이너에서 SameBeanConfig Bean을 불러와서 사용할 수 있게 된다. (의존관계 주입 성공)
궁금증 해결! (내 추측은 조금이지만 맞은 것 같다 ㅎㅎ)
'Java & Kotlin > Spring' 카테고리의 다른 글
Dependency LookUp (0) | 2022.08.12 |
---|---|
[Spring]빈 등록과 의존관계 주입 (0) | 2022.08.04 |
스프링 부트 공부 (10), AOP (0) | 2022.03.20 |
스프링 부트 공부 (9), 스프링 DB 접근 기술 (0) | 2022.03.12 |
스프링 부트 공부 (8), 회원관리 예제 - 웹 MVC 개발 (0) | 2022.03.06 |