일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 다형성
- over()
- 붕대 감기
- 멀티태스킹
- 리눅스
- 붕대 감기 자바
- continue 사용법
- 객체지향
- java
- 프로그래머스
- 쿠키
- 중첩 break
- break 사용법
- 오버로딩
- hackerrank
- 자바의 정석
- 혼공얄코
- 자바의정석
- contiune
- 프로그래머스 붕대 감기
- 티스토리챌린지
- 캡슐화
- 입출력
- spring security
- spring security 설정
- SQL Mapper
- CPU
- 오버라이딩
- 멀티프로세싱
- 오블완
- Today
- Total
쉽게 쉽게
[Spring] static 변수에 autowired 설정 방법 본문
▤ 목차
1. 이슈
공통적으로 사용하는 CommonService에서 모든 컨트롤러에서 사용될 public static void 메서드가 하나 있을 때, 이 static void 필드에 @Autowired된 빈을 사용해야 하는 상황이 발생했다.
그러나 그냥 static에 @Autowired된 빈을 사용하면 NullpointerException이 발생하게 된다.
@Service
public class CommonService {
@Autowired
private MyBean myBean;
public static void commonMethod() {
myBean.doSomething(); // myBean이 주입되지 않으므로 NPE 발생
}
}
그 이유는 @Autowired는 인스턴스 필드나 메서드, 생성자에 주입되도록 설계되어 있으며, static 컨텍스트에서는 인스턴스에 종속된 빈을 주입할 수 있는 방법이 없다.
사용할 수 없는 이유
@Autowired 애노테이션은 Spring이 해당 필드, 생성자, 또는 메서드에 주입할 객체를 자동으로 찾아서 주입해주는 기능을 제공한다. 이는 주로 객체의 인스턴스 필드나 메서드에서 사용된다.
static은 클래스 레벨에서 공유되는 변수를 정의한다. 즉, static 변수나 메서드는 해당 클래스를 통해 직접 접근할 수 있으며, 클래스의 인스턴스와는 무관하게 존재한다.
즉
1. @Autowired는 Spring 컨테이너가 관리하는 빈 인스턴스의 필드에 의존성을 주입하는 반면, static 변수나 메서드는 클래스 레벨에서 존재하며, 특정 인스턴스와 연결되지 않는다.
2. Spring의 빈은 애플리케이션 컨텍스트에 의해 관리되며, 그 생명주기는 애플리케이션 컨텍스트에 의해 제어되는 반면 static 필드는 클래스 로딩 시점에 초기화되며, 애플리케이션 컨텍스트와는 별개로 존재한다.
때문에 @Autowired된 빈을 static 메서드에서 직접 사용할 수 없다.
원래라면 Spring에서 @Autowired된 빈을 static 메서드에서 직접 사용할 수 없지만 몇 가지 방법을 통해 static 메서드에서 빈을 사용하는 방법을 알아봤다.
2. 해결방법
1. setter 사용
@Service
public class CommonService {
public static MyBean MyBean;
// MyBean의 setter 메서드를 사용
@Autowired
public void setMyBean(MyBean Object) {
this.MyBean = Object;
}
public static void commonMethod() {
myBean.doSomething();
}
}
2. 생성자 사용
@Service
public class CommonService {
public static MyBean MyBean;
// MyBean의 생성자를 이용
@Autowired
private CommonService(MyBean Object) {
this.MyBean = Object;
}
public static void commonMethod() {
myBean.doSomething();
}
}
3. @Postconstruct 사용
@Service
public class CommonService {
public static MyBean MyBean;
@Autowired
private MyBean Object;
@PostConstruct
private void initialize() {
this.MyBean = Object;
}
public static void commonMethod() {
myBean.doSomething();
}
}
@Postconstruct란?
스프링 빈 생명주기(Bean LifeCycle) 사이클은 아래와 같다.
스프링 컨테이너 생성 -> 스프링 빈 생성 -> 의존 관계 주입 -> 초기화 콜백 -> 사용 -> 소멸 콜백 -> 스프링 종료
- 초기화 콜백(init) : Bean이 생성되고, Bean의 의존성 주입이 완료된 뒤 호출된다.
- 소멸 콜백(destroy) : 스프링이 종료되기 전, Bean이 소멸되기 직전에 호출된다.
스프링 빈으로 등록되는 객체를 사용하기 위해서는 객체가 생성된 후 의존성 주입까지(Dependency Injection) 끝나야 해당 객체를 사용할 수 있게 된다.
@PostConstruct은 빈이 생성되고 의존 관계 주입이 완료된 후 실행되는 초기화 콜백을 적용할 수 있는 어노테이션이다.
즉 빈의 모든 의존성이 주입된 후에 추가적인 초기화 작업을 수행할 수 있다.
또한 @PostConstruct는 bean lifecycle에서 오직 한 번만 수행된다는 것을 보장할 수 있다.
그래서 @PostConstruct를 사용하면 bean이 여러 번 초기화되는 것을 방지할 수 있다.
https://madplay.github.io/post/spring-framework-static-field-injection
https://innovation123.tistory.com/213
잘못된 내용이 있다면 지적부탁드립니다. 방문해주셔서 감사합니다. |
'개발공부 > Spring' 카테고리의 다른 글
[Spring] Spring Security 구현 (1) - 설정 (1) | 2024.10.31 |
---|---|
[Spring] tiles 적용 (5) | 2024.09.05 |
[Spring] 스케줄러 구현 (1) | 2024.06.30 |
[Spring] 게시글 조회수 중복방지 (1) | 2024.05.30 |
spring tiles 사용법 (0) | 2023.06.25 |