views:

278

answers:

2

I realize this is a slightly funky thing to need to do, but I'm trying to access my Spring messageSource bean from a custom Velocity tool.

In most of our codebase, I'm able to just set up a member variable and load it like this:

@Resource(name = "messageSource")
private AbstractMessageSource _msgSource;

However, in this circumstance, this doesn't load the bean, I'm assuming because the Velocity tools get instantiated in a way that doesn't allow normal bean loading to occur. Or it doesn't want to initialize the bean for an application scoped Velocity tool.

The tool is set up in the toolbox.xml as follows:

<tool>
    <key>calendarTool</key>
    <scope>application</scope>
    <class>...</class>
</tool>

I haven't been able to find anything online that explains either how to do this or why it doesn't work.

A: 

Not sure why it doesn't work, but have you tried retrieving it without annotations, something like:

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
AbstractMessageSource _msgSource = (AbstractMessageSource )ctx.getBean("messageSource");
serg
A: 

What I've done is in the code where I render the Velocity template, I retrieve the message source from the applicationContext using applicationContext.getBean("messageSource") and then I put that MessageSource directly into the the VelocityContext that I use to render my templates under the key "messageSource" :

VelocityContext velocityContext = new VelocityContext();
velocityContext.put("messageSource", applicationContext.getBean("messageSource"));

Then, anytime I want to render a message key, say in an HTML email, it looks something like :

<td>messageSource.getMessage("my.message.key", null, $locale)</td>

where $locale is a java.util.Locale object that I've also manually placed in the VelocityContext. If I ever need any arguments to the message, then I use the list tool I've put in the context to get an array from the list of arguments I'll typically create right there in the template. As a side note, you can use the helper methods in the org.springframework.ui.velocity.VelocityEngineUtils class to help you out with rendering Velocity templates in your controllers or webflow code, or wherever else you may be rendering templates.

Alex Marshall