is there an elegant way to inject a spring managed bean into a java custom/simple tag is there an elegant way to inject a spring managed bean into a java custom/simple tag spring spring

is there an elegant way to inject a spring managed bean into a java custom/simple tag


You are correct there isn't a simple way to use dependency-injection in jstl tags, because they are not managed by spring, and cannot be. However there are (at least) two workarounds:

  • @Configurable - aspectJ allows you to plug a weaver at load-time/compile-time, so that even objects that are not instantiated by spring can be spring aware. See here

  • You can create a base tag class for your project, and call an init(..) method from every doStartTag(..) method. There, you can get the ServletContext from the pageContext, and thus obtain the spring ApplicationContext (via ApplicationContextUtils). Then:

    AutowireCapableBeanFactory factory = appCtx.getAutowireCapableBeanFactory();factory.autowireBean(this);

Neither options are perfect as they require either some additional code, or some "black magic"


To expand on @Bozho's post, I have gotten this to work like so: (in spring 3.0 there is no ApplicationContextUtils that I could find)

public class LocationTag extends RequestContextAwareTag {    @Autowired    PathComponent path;...    @Override    protected int doStartTagInternal() throws Exception {        if (path == null) {            log.debug("Autowiring the bean");            WebApplicationContext wac = getRequestContext().getWebApplicationContext();            AutowireCapableBeanFactory acbf = wac.getAutowireCapableBeanFactory();            acbf.autowireBean(this);        }        return SKIP_BODY;    }}


The solution as described above works but some background and additional code snippets are, quite likely, useful.

1) The doStartTagInternal method is invoked from the doStartTag method. 2) I was forced to set the pageContext first before invoking the doStartTag 3) I did a lookup of the bean as opposed to the autowiring. To me this seems more straightforward: (YourBeanProxy) autowireCapableBeanFactory.getBean("yourBeanName")

Hopefully this additional info is useful.