0

Config:

@Configuration
public class CoreConfig {

    @Bean
    public StatusService statusService(StatusPersistenceService statusPersistenceService) {
        return new StatusEventHandler(statusPersistenceService);
    }
}

Class Spring is complaining doesn't have a default constructor

@Configuration
public class StatusEventHandler implements StatusService {

    private final StatusPersistenceService statusPersistenceService;

    @Autowired
    public StatusEventHandler(final StatusPersistenceService statusPersistenceService) {
        this.statusPersistenceService = statusPersistenceService;
    }

}

Controller where this bean is injected:

@Controller
@RequestMapping("/showStatus")
public class ShowStatusController {

    @Autowired
    private StatusService statusService;

}

This compiles and the test passes, but when publishing to the app server, I get the below error. Why does Spring think there should be a default no-arg constructor?

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'statusEventHandler' 

...

No default constructor found;
roark
  • 792
  • 1
  • 12
  • 29
  • Do you have a `@ComponentScan` on your `CoreConfig` class? – Sotirios Delimanolis Oct 03 '13 at 21:16
  • No I don't have `@ComponentScan` on the `CoreConfig` class. Should I? Otherwise Spring won't know about StatusEventHandler for example? – roark Oct 03 '13 at 21:31
  • Nevermind, just see @Boris' answer. – Sotirios Delimanolis Oct 03 '13 at 21:32
  • @SotiriosDelimanolis OP also needs to define persistence service bean in the core Config i.e. to autoscan for it or add it as a `@Bean`. But tbh my local time is 2pm there are lot of examples at http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/context/annotation/Configuration.html – Boris Treukhov Oct 03 '13 at 21:44

2 Answers2

2

From @Configuration javadoc :

@Configuration is meta-annotated with @Component, therefore @Configuration classes are candidates for component scanning (typically using Spring XML's element) and therefore may also take advantage of @Autowired/@Inject at the field and method level (but not at the constructor level).

@Component, or @Service is more appropriate annotation for services, actually they are processed differently, but in this case you have already declared your bean with @Bean so you don't need to use @Component and neither any other component scan annotations(@Service, @Repository etc..) because the StatusService bean is already defined via @Bean annotated method.

update as noted by Sotirios Delimanolis, Spring process @Bean annotated methods should not contain arguments

   @Configuration
   public class CoreConfig {
     @Bean
     public StatusPersistenceService statusPersistenceService(){
     ....
     }

     @Bean
     public StatusService statusService() {
        return new StatusEventHandler(statusPersistenceService());
    }
 }

See http://docs.spring.io/spring/docs/3.2.x/javadoc-api/org/springframework/context/annotation/Bean.html

Community
  • 1
  • 1
Boris Treukhov
  • 17,493
  • 9
  • 70
  • 91
  • 1
    This is the correct answer. Note that `@Bean` methods do not accept parameters. OP, you would've seen more errors later on. – Sotirios Delimanolis Oct 03 '13 at 21:20
  • I have statusPersistenceService `@Bean` defined in `PersistenceConfig`. So should the statusService `@Bean` in `CoreConfig` not accept a parameter? Do I `Autowire` statusPersistenceService in that case? – roark Oct 04 '13 at 01:44
  • You can add autowired annotated field statusPersistenceService to CoreConfig and pass it to the statusService. CoreConfig should be aware of PersistenceConfig to make it possible. You can add PersistenceConfig as classes parameter of Configuration annotation to CoreConfig to achieve this. – Boris Treukhov Oct 04 '13 at 04:37
  • Do you have a link to the reference for this? I can't find it. `@ContextConfiguration(classes = { PersistenceConfig.class })` is that what you mean by adding a classes parameter? – roark Oct 04 '13 at 14:10
  • My bad! Yes I mean `@ContextConfiguratation` of test context framework. If you want to add one `@Configuration` to another you should use `@Import`, sorry for adding confusion. See `Composing @Configuration classes` at http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/context/annotation/Configuration.html – Boris Treukhov Oct 04 '13 at 14:51
0

Did you give the @Component or @Service annotation in the StatusEventHandler? Please try doing that.

Nicky Jaidev
  • 447
  • 1
  • 4
  • 12