mibutec
mibutec

Reputation: 2997

Spring MVC and custom tags

I want to use spring-beans in my custom taglibs in a spring-mvc application. Cause TagLib-Instances aren't instantiated by spring, I can't use dependnecy-injection.

My next thought was to add the spring-context by an interceptor to the request and get it from request within the tag-class.

Is there a better way to use spring in taglibs? Is there something ready-to-use in spring? If theres not already customtag-support in spring-mvc, is there a way to populate an exisiting object with dependencies?

public class MyTag extends TagSupport {
  @Autowired 
  private MyObject object;

  public void setMyObject(MyObject myObject) {
    this.myObject = myObject;
  }

  public int doEndTag() {
    ApplicationContext context = request.getAttribute("context");
    context.populate(this);

    return object.doStuff();
  }
}

Upvotes: 6

Views: 8087

Answers (3)

mibutec
mibutec

Reputation: 2997

Finally, the working way to do this was to declare the fields that should be initiated by spring as static and let initiate one Tag-instance

public class MyTag extends TagSupport {
  private static MyObject myObject;

  @Autowired
  public void setMyObject(MyObject myObject) {
    MyTag.myObject = myObject;
  }

  public int doEndTag() {
    return object.doStuff();
  }
}

Upvotes: 3

Angus
Angus

Reputation: 128

In your controller, put the object into the model.

The object can now be found in the HttpRequest object that is part of your tag.

Controller:

model.addAttribute("item", item);

Jsp File:

 <%= ((com.content.CmsItem)(request.getAttribute("item"))).getId() %>

If you must autowire, check out my solution on 'is there an elegant way to inject a spring managed bean into a java custom/simple tag'

Upvotes: 0

Benjamin Muschko
Benjamin Muschko

Reputation: 33476

You should prefer to put that logic into your controller. If you really need to do that you can write a utility class to retrieve beans from the application context.

public class AppContextUtil implements ApplicationContextAware 
{
    private static final AppContextUtil instance = new AppContextUtil();
    private ApplicationContext applicationContext;

    private AppContextUtil() {}

    public static AppContextUtil getInstance() 
    {
        return instance;
    }

    public <T> T getBean(Class<T> clazz) 
    {
        return applicationContext.getBean(clazz);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException 
    {
        this.applicationContext = applicationContext;
    }
}

You would then be able to retrieve your bean like this:

AppContextUtil.getInstance().getBean(MyObject.class);

Upvotes: 2

Related Questions