Configuration Using Annotation @Springbootapplication

Configuration using annotation @SpringBootApplication

The Spring Boot documentation for @SpringBootApplication states

Many Spring Boot developers always have their main class annotated
with @Configuration, @EnableAutoConfiguration and @ComponentScan.
Since these annotations are so frequently used together (especially if
you follow the best practices above), Spring Boot provides a
convenient @SpringBootApplication alternative.

The @SpringBootApplication annotation is equivalent to using
@Configuration, @EnableAutoConfiguration and @ComponentScan with their
default attributes
: [...]

where the @ComponentScan javadoc states

If specific packages are not defined, scanning will occur from the
package of the class that declares this annotation.

That is, only the types that are in the same package as your ReadingListApplication will be scanned.

If you want a custom configuration, provide your own @Configuration, @EnableAutoConfiguration, and @ComponentScan, as appropriate.

Why Spring Boot Application class needs to have @Configuration annotation?

You understood it right.

@Configuration

@Configuration is an analog for xml file. Such classes are sources of bean definitions by defining methods with the @Bean annotation.

@Configuration is:

  • not required, if you already pass the annotated class in the sources parameter when calling the SpringApplication.run() method;
  • required, when you don't pass the annotated class explicitly, but it's in the package that's specified in the @ComponentScan annotation of your main configuration class.

For readability, classes that are even explicitly passed as sources may anyway be annotated with @Configuration - just to show the intentions more clearly.

Your current class is not really source of bean definitions, because it doesn't have any, but if you had @Bean annotated methods, Spring would see them.

@EnableAutoConfiguration

Can be used with or without @Configuration. It tells Spring to setup some basic infrastructure judging by what you have in the classpath. It's done by invoking a so called import class that's derived from the value of the @Import annotation that @EnableAutoConfiguration includes. Only one class should be annotated with @EnableAutoConfiguration, duplicating it doesn't do anything.

This answer may also be helpful to understand the Spring Boot initialization process: Which piece of code in Spring Boot actually registers dispatcher servlet for SpringMVC?

How do I use a configuration class to configure properties for my application in Spring Boot?

Here lies the problem

@Autowired
public ---> static <---- Config configuration;

Spring can't autowire static fields. You need to remove static from the autowired field

Then you would not be able to use this field inside the main method because main is declared as static. The solution here is the following. You need to retrieve the bean after the application context is loaded programmatically without the use of @Autowired

@SpringBootApplication
public class DemoApplication {

public static void main(String[] args) {

ConfigurableApplicationContext ctx = SpringApplication.run(DemoApplication.class, args);

Config configuration = ctx.getBean(Config.class);

String fullname = configuration.name + " " + configuration.surname + " " + configuration.age;
System.out.println(fullname);
}

}

Is @SpringBootApplication able to find and AutoConfigure all dependency's beans without META-INF/spring.factories?

Component Scanning would scan the packages that you give it. You could technically tell it to scan all the packages of your dependencies, too, and it would start loading up any beans defined in them. If you don’t specify any packages to scan, then Spring will use the base package where the annotation is applied, which would very likely not include beans defined in any dependency libs.

There’s another layer to this- a lot of the libraries you use may be using annotations like “@AutoConfigureBefore” to give spring instructions on the order of bean creation. Component Scanning will not respect that, which could result in some weird behaviors if some dependency tries to override a bean from another which is annotated with @ConditionalOnMissingBean (I.e. create this bean only if it doesn’t exist.) You could easily end up with name collision issues where that bean actually gets created first, and then the override bean is created, too.

So the answer seems to be no. You need spring.factories.

how does @SpringBootApplication actually work in spring boot?

The @SpringBootApplication annotation is an annotation that is annotated with, among others, the annotations @ComponentScan and @EnableAutoConfiguration you mentioned. Instead of scanning for @SpringBootApplication, Spring internally scans for these (implicit) annotations and does its magic accordingly.

How is @ConfigurationProperties-annotated classes detected automatically with @SpringBootApplication Annotation

Following is what I understand from my analysis.

@ConfigurationProperties annotated types can be registered to the ApplicationContext by

  1. Annotating the class with @ConfigurationProperties with an
    annotation that falls in the scope of @ComponentScan (
    @Component, @Service and the like ) . Not recommended as per the comment from Stephane Nicoll , which makes sense to me now.

  2. Using annotation
    @EnableConfigurationProperties . For this to
    work the class annotated with @EnableConfigurationProperties
    should be annotated with an annotation that falls in the scope of
    @ComponentScan ( @Component, @Service and the like )

  3. Using annotation @ConfigurationPropertiesScan and by making sure
    the classes annotated with @ConfigurationProperties is placed
    under its radar. The usage is similar to @ComponentScan .

Now , when we replace @SpringBootApplication with individual annotations that it enables and omit @ComponentScan (as in example) , the @EnableConfigurationProperties way (Point 2) of registering the types with @ConfigurationProperties will not work. This probably answers both my questions on why and how .

This was explicitly mentioned probably because the connection between @EnableConfigurationProperties and @ComponentScan is not that obvious for people like me.

Additional details.

The registration of @ConfigurationProperties annotated types when we use @EnableConfigurationProperties happens through of the EnableConfigurationPropertiesRegistrar class that is imported by the annotation

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EnableConfigurationPropertiesRegistrar.class)
public @interface EnableConfigurationProperties {..}


Related Topics



Leave a reply



Submit