如何在我的春季项目中编写标签?

我想在我的spring框架中编写我的标签(扩展TagSupport )。 在我的标签类中,将使用一些应该在spring自动注入的服务。 但我总是得到null,似乎spring无法在我的标记类中注入服务实例。

代码如下:

 public class FetchTagNameTag extends TagSupport { @Autowired private TaskService taskService; ... 

taskService始终为null。

我该如何解决这个问题? 谢谢。

JSP标记对象不由Spring管理,它们由servlet容器管理。 因此,您无法将内容自动装入标签中。

如果您需要从spring appcontext获取bean,那么您的Spring MVC控制器需要将bean设置为请求属性(使用request.setAttribute() ),以便标记对象可以获取它。

尝试使用RequestContextAwareTag 。 它将为您提供获取RequestContext和WebApplicaitonContext的方法。 看看这里 。

使用@Configurable注释Tag-Implementation并将到Spring-Configuration中。

在弹簧参考文档和弹簧源中查看这些弹簧包:

  • org.springframework.web.servlet.tags
  • org.springframework.web.servlet.tags.form
  • 如果没有别的,那些将向您展示弹簧开发人员如何编写spring标签。

    你可以做的是创建一个这样的静态方法:

     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只有一个,它应该不是问题。 您甚至可以更进一步创建一个辅助超类,它始终保证自动assembly:

     public class SpringTagSupport extends TagSupport { public SpringTagSupport() { super(); YourHelperClass.autowireAllFor(this); } } 

    其余的就像从SpringTagSupport扩展类一样简单。

    首先我写这个:

     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("slot for user:"+userDetail.getUserId()+""); } @Override protected void initCustomBeans() { userDetail = (UserDetailHolder) getSpringContext().getBean("userDetailHolder"); } } 

    这是工作。 但是我发现了这个: Spring支持的Tag Libraries 。 在我的progect真相我仍然使用自己的解决方案。

    使用 :-

     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; }