This is something I've not needed to do before. It's quite normal to need to call static factory methods to create beans in Spring because the static Singleton pattern is so common. Slightly less usual is the need to call a factory method on a bean instance and pass in parameters. Less usual, but not unheard of, and I had a need to do this today.
The case in question was to provide Javascript functionality to a Spring bean. JSR223 (implemented in Java 6) provides suitable classes for implementing these. Here's the code I started with:
final ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("js"); final ScriptContext ctx = scriptEngine.getContext(); // ... Remaining code using this Javascript script context.
The problem here is that I need to instantiate the ScriptEngineManager class, then call the getEngineByName() method, and pass in the "js" string as a parameter. This took me a few minutes to work out. If it's conspicuously documented in the Spring reference then I missed it, and the parameter passing syntax is slightly counterintuitive:
<bean id="scriptEngineManager" class="javax.script.ScriptEngineManager"/> <bean id="scriptEngine" factory-method="getEngineByName" factory-bean="scriptEngineManager"> <constructor-arg value="js"/> </bean> <bean id="scriptUser" class="com.fatmoggy.examples.ScriptUser"> <property name="scriptEngine" ref="scriptEngine"/> </bean>
Note that I create the ScriptEngineManager as a normal Spring bean (ok so far), then use the factory-method attribute specifying a factory-bean in order to call the dynamic method. You also have to use the constructor-arg element in the bean configuration to specify the parameter that is to be passed - that's consistent but not very intuitive; it would be nice to have an alias for this to make it clearer. Still, having configured the above, I can now inject the ScriptEngine instance into my custom ScriptUser class, the implementation of which is shown below:
public class ScriptUser { private ScriptEngine scriptEngine; public void foo() { final ScriptContext ctx = scriptEngine.getContext(); // ... Remaining code using this Javascript script context. } @Required public void setScriptEngine(final ScriptEngine scriptEngine) { this.scriptEngine = scriptEngine; } }