custom taglib 만들면서 User 객체 사용하려고 @Autowired 어노테이션이용해서 User 객체를 DI 받았는데
User 객체 값을 찍어보면 계속 null이 나왔다.
public class UserTag extends TagSupport {
@Autowired
private User user;
public int doStartTag() throws Exception {
// user 객체는 null 이 된다.
System.out.println(user);
...
}
}
왜 그럴까 검색에 검색을 해보니 너무도 당연한 거였다 -_-
Spring 기초내공이 부족하니 이런 단순한 개념도 이해를 못했던 것이다.
@Autowired 어노테이션 이용한 객체는 Spring 컨테이너에서 생성된 빈이기 때문에 Spring이 관리하는 빈이지만
tag library는 서블릿에서 생성되기때문에 Spring 관리대상이 아니다.
그렇기 때문에 custom taglib 만드는 자바코드에서 @Autowired를 사용해도 객체를 DI 받을수 없었던것이다.
이거에 대한 해결 방법은 아래와 같이 2가지 방법이 있다. (더 있을수도 있다 -_-)
해결 방법역시 간단하다. WebApplicationContext에 현재 등록된 빈을 찾아서 가져오는거다.
Spring 컨테이너내에서는 Spring 알아서 찾아주지면 그렇지 않은 곳에서는 아래와 같은 방법으로 직접 찾아서 이용하면 된다.
1. RequestContextAwareTag를 이용하는 방법
public class UserTag extends RequestContextAwareTag {
private User user;
public int doStartTagInternal() throws Exception {
user = (User) getRequestContext().getWebApplicationContext().getBean(User.class);
...
}
}
2. TagSupport를 이용하는 방법
public class UserTag extends TagSupport {
private User user;
public int doStartTag() throws Exception {
ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(pageContext.getServletContext());
user = ctx.getBean(User.class);
...
}
}
추가로,
@Configurable 과 Aspect를 이용해서 Spring관리대상이 아닌 빈들은 Spring관리대상으로 포함시켜서 DI 하는 방법이 있다는데 그건 확인 안해봤다.