我想在我的spring框架中编写我的标记(extends TagSupport
)。在我的标签类中,将使用一些应该在春天自动注入的服务。但我总是得到null,似乎spring无法在我的标记类中注入服务实例。
代码如下:
public class FetchTagNameTag extends TagSupport {
@Autowired
private TaskService taskService;
...
taskService
始终为空。
我该如何解决这个问题? 感谢。
答案 0 :(得分:15)
尝试使用RequestContextAwareTag
。它将为您提供获取RequestContext和WebApplicaitonContext的方法。看看here。
答案 1 :(得分:4)
JSP标记对象不由Spring管理,它们由servlet容器管理。因此,您无法将内容自动装入标签中。
如果您需要从spring appcontext获取bean,那么您的Spring MVC控制器需要将bean设置为请求属性(使用request.setAttribute()
),以便标记对象可以获取它。
答案 2 :(得分:1)
使用@Configurable
为您的代码实现添加注释,并将<context:component-scan base-package="your.webapp">
添加到Spring-Configuration。
答案 3 :(得分:0)
在弹簧参考文档和弹簧源中查看这些弹簧包:
如果没有别的,那些会告诉你弹簧开发者如何编写spring标签。
答案 4 :(得分:0)
你可以做的是创建一个这样的静态方法:
public static void autowireAllFor(Object target) {
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
bpp.setBeanFactory(...yourBeanFactory...);
bpp.processInjection(target);
}
然后为你的标签做
public class YourTag extends TagSupport {
@Autowired
private SomeBean someBean;
public YourTag() {
YourHelperClass.autowireAllFor(this);
}
}
这种方法的明显缺点是你必须为每个构造函数执行此操作,但由于TagSupport
只有一个,它应该不是问题。您甚至可以更进一步创建一个辅助超类,它始终保证自动装配:
public class SpringTagSupport extends TagSupport {
public SpringTagSupport() {
super();
YourHelperClass.autowireAllFor(this);
}
}
其余的就像从SpringTagSupport
扩展课程一样简单。
答案 5 :(得分:0)
首先我写这个:
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;
}
用法:
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");
}
}
这是工作。 但是我发现了这个: Spring supported Tag Libraries。在我的progect真相我仍然使用自己的解决方案。
答案 6 :(得分:0)
使用: -
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;
}