Reputation: 2847
I want to write my tag (extends TagSupport
) in my spring framework. In my tag class, will use some service which should auto inject by spring. But I always get null, seems spring can't inject service instance in my tag class.
The code is like the following:
public class FetchTagNameTag extends TagSupport {
@Autowired
private TaskService taskService;
...
taskService
is always null.
How can I resolve this? Thanks.
Upvotes: 8
Views: 6859
Reputation: 1
Use :-
import org.springframework.web.servlet.tags.RequestContextAwareTag;
public class FetchTagNameTag extends RequestContextAwareTag {
// @Autowired
// private TaskService taskService;
@Override
protected int doStartTagInternal() throws Exception {
TaskService taskService= getRequestContext().getWebApplicationContext().getBean(TaskService.class);
return 0;
}
Upvotes: 0
Reputation: 10362
First I write this:
public abstract class SpringSuportedTag extends SimpleTagSupport{
protected WebApplicationContext _applicationContext;
protected WebApplicationContext getSpringContext(){
PageContext pageContext = (PageContext) getJspContext();
if(_applicationContext==null){
_applicationContext = RequestContextUtils.getWebApplicationContext(
pageContext.getRequest(),
pageContext.getServletContext()
);
initCustomBeans();
}
return _applicationContext;
}
protected abstract void initCustomBeans();
/**
* Deprecated for inserting extra logic. Use {@link #doTagWithSpring()} instead.
*/
@Override
@Deprecated
public void doTag() throws JspException, IOException {
getSpringContext();
doTagWithSpring();
}
abstract void doTagWithSpring() throws JspException, IOException;
}
And usage:
public class SlotTag extends SpringSuportedTag {
// @Resource(name="userDetailHolder")
// not work here
UserDetailHolder userDetail;
private String slotname;
public String getSlotname() {
return slotname;
}
public void setSlotname(String slotname) {
this.slotname = slotname;
}
@Override
void doTagWithSpring() throws JspException, IOException {
PageContext pageContext = (PageContext) getJspContext();
String userDetailCode = pageContext.getAttribute(InitWidgetUserTag.KAY_USERDETAIL, PageContext.PAGE_SCOPE).toString();
userDetail.init(userDetailCode);
String pageID = pageContext.getAttribute(InitWidgetUserTag.KAY_PAGEID, PageContext.PAGE_SCOPE).toString();
getJspContext().getOut().println("<b>slot for user:"+userDetail.getUserId()+"</b>");
}
@Override
protected void initCustomBeans() {
userDetail = (UserDetailHolder) getSpringContext().getBean("userDetailHolder");
}
}
It's work. But than i found this: Spring supported Tag Libraries. Truth in my progect I still use own solution.
Upvotes: 0
Reputation: 26713
What you could do is create a static method like this:
public static void autowireAllFor(Object target) {
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(...yourBeanFactory...);
bpp.processInjection(target);
}
and then for your tag you could do
public class YourTag extends TagSupport {
@Autowired
private SomeBean someBean;
public YourTag() {
YourHelperClass.autowireAllFor(this);
}
}
The obvious disadvantage of this approach is that you have to do this for every constructor, but as TagSupport
only has one, it should not be a problem. You can go even one step further and create a helper superclass which always guarantees autowiring:
public class SpringTagSupport extends TagSupport {
public SpringTagSupport() {
super();
YourHelperClass.autowireAllFor(this);
}
}
The rest is as easy as extending your classes from SpringTagSupport
.
Upvotes: 0
Reputation: 1308
Have a try by utilizing RequestContextAwareTag
. It will offer you methods to obtain RequestContext and then WebApplicaitonContext. Have a look at here.
Upvotes: 16
Reputation: 621
Annotate your Tag-Implementation with @Configurable
and add <context:component-scan base-package="your.webapp">
to your Spring-Configuration.
Upvotes: 1
Reputation: 38300
Check out these spring packages in the spring reference docs and in the spring source:
If nothing else, those will show you how the spring developers wrote the spring tags.
Upvotes: 0
Reputation: 403481
JSP tag objects are not managed by Spring, they are managed by the servlet container. As a result, you cannot autowire stuff into your tags.
If you need to get hold of beans from the spring appcontext, then your Spring MVC controller needs to set the bean as a request attribute (using request.setAttribute()
), so that the tag object can get hold of it.
Upvotes: 5