2

I've searched for an answer to this question but my search voodoo must be a little off.

At work I've noticed there's a preference to use Spring Configuration and @Beans to initialise our Java objects. While there is no problem with this approach I thought switching over to @Component (with ComponentScan) might

  1. Slightly simplify the code
  2. Put us more inline with good Spring practices

But, thinking about it, I'm having trouble justifying why I consider it a good practice. My understanding of @Bean is that it's useful for initialising legacy or non-Springified, code. That may be causing me to consider @Component as a good practice.

An advantage to the @Bean approach is that it centralises the initialisation. This is a little easier to understand in contrast to @Component which is not as immediately intuitive.

Does Spring have any good documentation on the pros and cons of each approach? Or a best practices guide for this topic?

Shane Gannon
  • 6,770
  • 7
  • 41
  • 64

1 Answers1

1

@Configuration class with @Bean-s inside it is called "Java based configuration". And it's more flexible, then "Annotation based configuration" (@Component).

It is perfectly valid to have Java configuration and annotated component scans in the same project because they server different purposes.

@Component (@Service, @Repository etc) are used to auto-detect and auto-configure beans.

@Bean annotation is used to explicitly declare a single bean, instead of letting Spring do it automatically. You can provide more settings to bean instantiated that way.

You can do the following with @Bean. But, this is not possible with @Component:

@Bean
public MyService myService(boolean someCondition) {
    if(someCondition) {
      return new MyServiceImpl1();
    } else {
        return new MyServiceImpl2();
    }
}
Pospolita Nikita
  • 635
  • 5
  • 15
  • Does the Spring community have any preference? Realistically with Component a mixed approach will always be used. Is there any reason to ignore Component and simply stick with Bean? – Shane Gannon Jun 25 '18 at 16:55
  • I can say that usually both approaches are used in projects. It's not one vs. another. Sometimes you need to configure beans from third-party libs, in this case you need to provide configured bean to context via Java-based configuration. – Pospolita Nikita Jun 25 '18 at 17:01
  • Also, Java-based configurations are very handy in integration tests – Pospolita Nikita Jun 25 '18 at 17:01
  • That was one of the noted benefits of Beans. But I've noticed it's possible to define a Component as a Bean for testing and it works. – Shane Gannon Jun 25 '18 at 17:03
  • I was talking about integration tests with small scope. When you use @ContextConfiguration annotation to provide only beans for tests. But answering to your question "Is there any reason to ignore Component and simply stick with Bean?" - no, there are no such reason – Pospolita Nikita Jun 25 '18 at 17:15
  • Thanks for the insight @Pospolita Nikita – Shane Gannon Jun 25 '18 at 17:17
  • 1
    Java based configuration _is_ preferable for testing as you only import the configuration classes you require to test whatever slice of the application you want to. e.g. `MyDatabaseConfigurion`, `MyServiceConfiguration`. ComponentScanning rapidly gets messy as you do not have a central point of reference to where beans are defined, and if you only want to test a slice of your application you will likely end up loading more than needed. Configuration classes give a central point of access. – Darren Forsythe Jul 18 '18 at 12:35