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 hereYou can create a base tag class for your project, and call an
init(..)
method from everydoStartTag(..)
method. There, you can get theServletContext
from thepageContext
, and thus obtain the springApplicationContext
(viaApplicationContextUtils
). 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.