如何在我的春季项目中编写标签?
我想在我的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中。
在弹簧参考文档和弹簧源中查看这些弹簧包:
如果没有别的,那些将向您展示弹簧开发人员如何编写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; }