Как написать тег в моем весеннем проекте? - PullRequest
8 голосов
/ 13 октября 2010

Я хочу написать свой тег (extends TagSupport) в моей весенней структуре.В моем классе тегов будет использоваться какой-то сервис, который должен автоматически внедряться к весне.Но я всегда получаю ноль, кажется, что Spring не может внедрить экземпляр службы в моем классе тегов.

Код выглядит следующим образом:

public class FetchTagNameTag extends TagSupport {

   @Autowired
   private TaskService taskService;
   ...

taskService всегда равно нулю.

Как я могу решить эту проблему?Благодаря.

Ответы [ 7 ]

15 голосов
/ 15 июня 2011

Попробуйте, используя RequestContextAwareTag. Он предложит вам методы для получения RequestContext, а затем WebApplicaitonContext. Взгляните на здесь .

4 голосов
/ 14 октября 2010

Объекты тегов JSP не управляются Spring, они управляются контейнером сервлета.В результате вы не можете автоматически связать материал с вашими тегами.

Если вам нужно получить bean-компоненты из Spring AppContext, тогда вашему контроллеру Spring MVC необходимо установить bean-компонент в качестве атрибута запроса (используя request.setAttribute()), чтобы объект тега мог получить его.

1 голос
/ 15 февраля 2011

Аннотируйте вашу реализацию тега с помощью @Configurable и добавьте <context:component-scan base-package="your.webapp"> к вашей Spring-конфигурации.

0 голосов
/ 27 апреля 2017

Использование: -

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;
   }
0 голосов
/ 26 апреля 2013

Сначала я пишу это:

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 .Правда в моем проекте я все еще использую собственное решение.

0 голосов
/ 19 декабря 2012

Что вы можете сделать, это создать статический метод, подобный этому:

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.

0 голосов
/ 18 октября 2010

Ознакомьтесь с этими комплектами пружин в справочных документах на пружину и в источнике:

org.springframework.web.servlet.tags org.springframework.web.servlet.tags.form

Если ничего другого, они покажут вам, как разработчики Spring написали теги Spring.

...