42

I was trying to create Hibernate Validator bean, and run into this problem creating a bean from static factory method in another Class. I found a Spring way to get my Validator bean initialized (solution at the bottom), but the problem itself remains unsolved. Validator is used as example case here.

This is how I create the Validator instance in Java

import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();

This is how I tried to create the bean in applicationContext.xml

<bean id="validatorFactory" 
    class="javax.validation.ValidatorFactory" 
    factory-method="javax.validation.Validation.buildDefaultValidatorFactory" />

<bean id="validator" 
    class="javax.validation.Validator" 
    factory-bean="validatorFactory"
    factory-method="getValidator" />

What I understand is that in "factory-method" you can only access static methods defined in the Class defined in the "class" parameter. Since the method buildDefaultValidatorFactory() is static I cant create a instance of Validation and give it as "factory-bean" for the validatorFactory like this:

<bean id="validation" class="javax.validation.Validation" />

<bean id="validatorFactory" 
    class="javax.validation.ValidatorFactory" 
    factory-bean="validation"
    factory-method="buildDefaultValidatorFactory" />

This ends up to error message

"Check that a method with the specified name exists and that it is non-static"

Question is how would you create bean in this kind of a situation in Spring?

This is how I solved the Validator problem:

<bean id="validator"
  class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
Spaideri
  • 514
  • 1
  • 5
  • 10

2 Answers2

52

The factory-method should only contain the method name, not including the class name.

If you want to use a static factory, give the class of the factory(!) to the bean declaration, if you want to use an instance factory, give the factory-bean to the bean declaration, but don't give both: The class of the created bean is not given in the bean declaration.

So a full example should look like this, using a static factory for validatorFactory and an instance factory for validator:

<bean id="validatorFactory" 
    class="javax.validation.Validation" 
    factory-method="buildDefaultValidatorFactory" />

<bean id="validator" 
    factory-bean="validatorFactory"
    factory-method="getValidator" />

See details on the documentation:

http://static.springsource.org/spring/docs/2.0.x/reference/beans.html#beans-factory-class-static-factory-method

To answer you question - How would you create bean in this kind of a situation in Spring? - Do it exactly as shown here, or if you can, use a utility class like the LocalValidatorFactoryBean, which simplifies the Spring configuration.

Christian Semrau
  • 8,913
  • 2
  • 32
  • 39
  • Class name is there to demonstrate what I wanted to do. As I said "What I understand is that in "factory-method" you can only access static methods defined in the Class defined in the "class" parameter." – Spaideri Mar 27 '12 at 07:56
  • 1
    That is correct - if you give the `class` parameter, the factory method must be a static method of that Class, as seen in the creation of `validatorFactory`. – Christian Semrau Mar 27 '12 at 13:10
0

Did you try this?

<bean id="validatorFactory" 
class="javax.validation.Validation" 
factory-method="buildDefaultValidatorFactory" />

<bean id="validator" 
class="javax.validation.Validator" 
factory-bean="validatorFactory"
factory-method="getValidator" />
chalimartines
  • 5,603
  • 2
  • 23
  • 33