먼저 목적은 아래와 같은 코드가 작동하게 하는 것이다.
@Component
public class Foo {
public void doA(){
System.out.println("doA");
}
}
public class Boo {
@Autowired
public static Foo foo;
}
public class ApplicationTests {
@Test
public void contextLoads() {
Boo.foo.doA();
}
}
물론 디자인 상으로는 클래스에 저장되는 static 자원에서 객체를 가리키게 하는 것은 좋지 않지만, 이런 상황에서 그나마 깔끔하게 처리하는 방법은 없을까?
문제점 :
- 먼저 @Autowired는 Spring에 의해서 관리되야 주입을 해주는데, Boo는 현재 그렇지 않다.
- 아무리 Boo에서는 클래스 레벨에서 Foo를 사용하고 싶다고 하더라도 객체는 클래스 로딩된 후에 생성되기 때문에 Boo 클래스가 로딩될 당시에 Foo 객체는 존재하지 않는다.
해결책 :
- Boo 도 싱글턴 객체로 스프링에서 관리되게 등록해준다.
- Boo 객체가 생성될 때 Foo 객체를 가져오고, static 필드에 넘겨준다.
먼저 첫번째 방법은 @PostContruct를 이용해서 static 필드에 값을 넘겨주는 방법이다.
@Component
public class Boo {
public static Foo foo;
@Autowired
private Foo fooInstance;
@PostConstruct
private void init() {
foo = fooInstance;
}
}
두번째 방법은 생성자에 @Autowired를 사용하는 방법이다.
@Component
public class Boo {
public static Foo foo;
@Autowired
private Boo(Foo foo) {
this.foo = foo;
}
}
생성자나 init 같은 함수들은 private으로 하더라도 Spring이 알아서 접근해서 호출해준다. 생성자에 @Autowired는 파라미터로 들어오는 bean을 주입시켜 준다.
참고 : http://stackoverflow.com/questions/17659875/autowired-and-static-method