blue-sky
blue-sky

Reputation: 53896

Class based on factory class not available for autowiring

I'm trying to learn the basics of Spring and have defined this class?

public class Processor {

    public Processor() {
        this.setup();
    }

    private void setup(){
       //run some setup code
    }

    public String processString(String str) {
        // process the string
        return str;
    }

}

I want to Spring enable this class so I use a factory bean:

Reading https://www.baeldung.com/spring-factorybean I use:

public class Processor implements FactoryBean<Processor> {

    @Override
    public Processor getObject() throws Exception {
        return new Processor();
    }

    @Override
    public Class<?> getObjectType() {
        return Processor.class;
    }
}

To Test:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ProcessorFactory.class)
public class ProcessorTest {

    @Autowired
    private Processor processor;

        @Test
    public void testProcessor() {
            //Some tests
        }
}

This works as expected.

When I try to use

@Autowired
private Processor processor;

elsewhere in my project I receive compile-time error :

Could not autowire. No beans of 'Processor' type found.

Have I not setup the factory correctly? I should annotate the Processor object to indicate it is to be autowired ? Perhaps this is not a valid use case for Factory ?

Upvotes: 0

Views: 340

Answers (1)

Mark Bramnik
Mark Bramnik

Reputation: 42531

In general, factory beans are pretty outdated, first spring versions indeed used this approach, but spring has evolved since that time.

The Factory bean itself should be registered in the spring configuration (the very first versions of spring used xml based configuration because Java Annotation did not exist at that time) so the tutorial contains the XML configuration example. Anyway, that's probably the reason of failure. In the test you should also specify the path to the xml configuration otherwise the factory bean won't be loaded.

You can use these factory beans (they're still supported) but they have the following downsides:

  1. They couple your code to the spring framework
  2. A lot of boilerplate (usually in typical application there can be hundreds of beans, so creating a Factory Bean for each one is an overkill).

So you can:

  1. Instead of using Factory Beans, annotate the Processor with @Component annotation (or more specialized @Service).

  2. Alternatively Use Java configuration:


@Configration
public class MyConfig {
  
  @Bean
  public Processor processor() {
      // optionally slightly customize the creation of the class if required;
      return new Processor();
  }
}

Upvotes: 2

Related Questions