Spring boot is very easy to use and it does a lot of things under the hood, you might not be aware of. In future, a good developer will be who will know exactly what is going on behind spring boot auto configuration, how to use it in your favor and how to disable certain sections which you do not want into your project.
To understand most basic things behind spring boot, we will create a minimum boot application with single dependency and single launch class file. We will then analyze the startup logs to get the insights.
Create Spring boot application with launch class
- Create a new maven project in eclipse with archetype “
maven-archetype-quickstart
“. - Update
pom.xml
file withspring-boot-starter-web
dependency and plugin information.<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd;<modelVersion>4.0.0</modelVersion>
<groupId>com.fusebes</groupId><artifactId>springbootdemo</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging>
<name>springbootdemo</name><url>http://maven.apache.org</url>
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.0.RELEASE</version></parent>
<properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties>
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
<repositories><repository><id>repository.spring.release</id><name>Spring GA Repository</name><url>http://repo.spring.io/release</url></repository></repositories></project>
- Create launch application.
package
com.fusebes.demo;
import
org.springframework.boot.SpringApplication;import
org.springframework.boot.autoconfigure.SpringBootApplication;import
org.springframework.context.ApplicationContext;
@SpringBootApplicationpublic
class
App {public
static
void
main(String[] args) {ApplicationContext ctx = SpringApplication.run(App.class, args);}}
What this launch class does?Above class is called spring boot application launch class. It used to Bootstrap and launch a Spring application from a Javamain()
method. It typically does following things –- Create an instance of Spring’s ApplicationContext.
- Enable the functionality to accept command-line arguments and expose them as Spring properties.
- Load all the Spring beans as per the configuration. You can do other operations as well as per project need arises.
@SpringBootApplication Annotation
This annotation is a shortcut of applying 3 annotations in one statement –
- @SpringBootConfiguration@SpringBootConfiguration is new annotation in Spring boot 2. Previously, we have been using @Configuration annotation. You can use
@Configuration
in place of this. Both are same thing.It indicates that a class provides Spring Boot application@Configuration
. It simply means that annotated class is a configuration class and shall be scanned for further configurations and bean definitions. - @EnableAutoConfigurationThis annotation is used to enable auto-configuration of the Spring Application Context, attempting to guess and configure beans that you are likely to need. Auto-configuration classes are usually applied based on your classpath and what beans you have defined.Auto-configuration tries to be as intelligent as possible and will back-away as you define more of your own configuration. You can always manually exclude any configuration that you never want to apply using two methods –i) Use excludeName()
ii) Using thespring.autoconfigure.exclude
property in properties file. e.g.@EnableAutoConfiguration
(excludeName = {
"multipartResolver"
,
"mbeanServer"
})
Auto-configuration is always applied after user-defined beans have been registered. - @ComponentScanThis annotation provides support parallel with Spring XML’s
context:component-scan
element.EitherbasePackageClasses()
orbasePackages()
may be specified to define specific packages to scan. If specific packages are not defined, scanning will occur from the package of the class that declares this annotation.
Run the launch application and check logs
Let’s start running it with the simplest option–running as a Java application. In your IDE, right-click on the application class and run it as Java Application. For getting insight of registered beans, I have added modified the launch application as below.
@SpringBootApplication public class App { public static void main(String[] args) { ApplicationContext ctx = SpringApplication.run(App. class , args); String[] beanNames = ctx.getBeanDefinitionNames(); Arrays.sort(beanNames); for (String beanName : beanNames) { System.out.println(beanName); } } } |
Now see the logs –
. ____ _ __ _ _/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/ ___)| |_)| | | | | || (_| | ) ) ) )' |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot :: (v2.0.0.RELEASE) 2018-04-02 13:09:41.100 INFO 11452 --- [ main] com.fusebes.demo.App : Starting App on FFC15B4E9C5AA with PID 11452 (C:\Users\zkpkhua\IDPPaymentTransfers_Integrated\springbootdemo\target\classes started by zkpkhua in C:\Users\zkpkhua\IDPPaymentTransfers_Integrated\springbootdemo)2018-04-02 13:09:41.108 INFO 11452 --- [ main] com.fusebes.demo.App : No active profile set, falling back to default profiles: default2018-04-02 13:09:41.222 INFO 11452 --- [ main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@4450d156: startup date [Mon Apr 02 13:09:41 IST 2018]; root of context hierarchy2018-04-02 13:09:43.474 INFO 11452 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)2018-04-02 13:09:43.526 INFO 11452 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]2018-04-02 13:09:43.526 INFO 11452 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.282018-04-02 13:09:43.748 INFO 11452 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext2018-04-02 13:09:43.748 INFO 11452 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2531 ms2018-04-02 13:09:43.964 INFO 11452 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]2018-04-02 13:09:43.969 INFO 11452 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]2018-04-02 13:09:43.970 INFO 11452 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]2018-04-02 13:09:43.970 INFO 11452 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]2018-04-02 13:09:43.970 INFO 11452 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]2018-04-02 13:09:44.480 INFO 11452 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@4450d156: startup date [Mon Apr 02 13:09:41 IST 2018]; root of context hierarchy2018-04-02 13:09:44.627 INFO 11452 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)2018-04-02 13:09:44.630 INFO 11452 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)2018-04-02 13:09:44.681 INFO 11452 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]2018-04-02 13:09:44.682 INFO 11452 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]2018-04-02 13:09:44.747 INFO 11452 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]2018-04-02 13:09:45.002 INFO 11452 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup2018-04-02 13:09:45.070 INFO 11452 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''2018-04-02 13:09:45.076 INFO 11452 --- [ main] com.fusebes.demo.App : Started App in 4.609 seconds (JVM running for 5.263)appbasicErrorControllerbeanNameHandlerMappingbeanNameViewResolvercharacterEncodingFilterconventionErrorViewResolverdefaultServletHandlerMappingdefaultValidatordefaultViewResolverdispatcherServletdispatcherServletRegistrationerrorerrorAttributeserrorPageCustomizererrorPageRegistrarBeanPostProcessorfaviconHandlerMappingfaviconRequestHandlerhandlerExceptionResolverhiddenHttpMethodFilterhttpPutFormContentFilterhttpRequestHandlerAdapterjacksonCodecCustomizerjacksonObjectMapperjacksonObjectMapperBuilderjsonComponentModulelocaleCharsetMappingsCustomizermappingJackson2HttpMessageConvertermbeanExportermbeanServermessageConvertersmethodValidationPostProcessormultipartConfigElementmultipartResolvermvcContentNegotiationManagermvcConversionServicemvcHandlerMappingIntrospectormvcPathMatchermvcResourceUrlProvidermvcUriComponentsContributormvcUrlPathHelpermvcValidatormvcViewResolverobjectNamingStrategyorg.springframework.boot.autoconfigure.AutoConfigurationPackagesorg.springframework.boot.autoconfigure.condition.BeanTypeRegistryorg.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfigurationorg.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfigurationorg.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfigurationorg.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration$StringHttpMessageConverterConfigurationorg.springframework.boot.autoconfigure.http.JacksonHttpMessageConvertersConfigurationorg.springframework.boot.autoconfigure.http.JacksonHttpMessageConvertersConfiguration$MappingJackson2HttpMessageConverterConfigurationorg.springframework.boot.autoconfigure.http.codec.CodecsAutoConfigurationorg.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration$JacksonCodecConfigurationorg.springframework.boot.autoconfigure.info.ProjectInfoAutoConfigurationorg.springframework.boot.autoconfigure.internalCachingMetadataReaderFactoryorg.springframework.boot.autoconfigure.jackson.JacksonAutoConfigurationorg.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$Jackson2ObjectMapperBuilderCustomizerConfigurationorg.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperBuilderConfigurationorg.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperConfigurationorg.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$ParameterNamesModuleConfigurationorg.springframework.boot.autoconfigure.jmx.JmxAutoConfigurationorg.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfigurationorg.springframework.boot.autoconfigure.validation.ValidationAutoConfigurationorg.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfigurationorg.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfigurationorg.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration$TomcatWebServerFactoryCustomizerConfigurationorg.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfigurationorg.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration$DispatcherServletConfigurationorg.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration$DispatcherServletRegistrationConfigurationorg.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfigurationorg.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfigurationorg.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfigurationorg.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration$EmbeddedTomcatorg.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfigurationorg.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfigurationorg.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapterorg.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter$FaviconConfigurationorg.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfigurationorg.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration$DefaultErrorViewResolverConfigurationorg.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfigurationorg.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfigurationorg.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration$TomcatWebSocketConfigurationorg.springframework.boot.context.properties.ConfigurationBeanFactoryMetadataorg.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessororg.springframework.context.annotation.internalAutowiredAnnotationProcessororg.springframework.context.annotation.internalCommonAnnotationProcessororg.springframework.context.annotation.internalConfigurationAnnotationProcessororg.springframework.context.annotation.internalRequiredAnnotationProcessororg.springframework.context.event.internalEventListenerFactoryorg.springframework.context.event.internalEventListenerProcessorparameterNamesModulepreserveErrorControllerTargetClassPostProcessorpropertySourcesPlaceholderConfigurerrequestContextFilterrequestMappingHandlerAdapterrequestMappingHandlerMappingresourceHandlerMappingrestTemplateBuilderserver-org.springframework.boot.autoconfigure.web.ServerPropertiesservletWebServerFactoryCustomizersimpleControllerHandlerAdapterspring.http.encoding-org.springframework.boot.autoconfigure.http.HttpEncodingPropertiesspring.info-org.springframework.boot.autoconfigure.info.ProjectInfoPropertiesspring.jackson-org.springframework.boot.autoconfigure.jackson.JacksonPropertiesspring.mvc-org.springframework.boot.autoconfigure.web.servlet.WebMvcPropertiesspring.resources-org.springframework.boot.autoconfigure.web.ResourcePropertiesspring.security-org.springframework.boot.autoconfigure.security.SecurityPropertiesspring.servlet.multipart-org.springframework.boot.autoconfigure.web.servlet.MultipartPropertiesstandardJacksonObjectMapperBuilderCustomizerstringHttpMessageConvertertomcatServletWebServerFactorytomcatServletWebServerFactoryCustomizertomcatWebServerFactoryCustomizerviewControllerHandlerMappingviewResolverwebServerFactoryCustomizerBeanPostProcessorwebsocketContainerCustomizerwelcomePageHandlerMapping |
You see how many beans got registered automatically. That’s beauty of spring boot. If you want to dig deeper into why any particular bean got registered? You can see that by putting a debug flag at application startup.
Simply pass -Ddebug=true
as VM argument.
Now when you run the application, you will get lots of debug logs having similar information :
CodecsAutoConfiguration.JacksonCodecConfiguration matched: - @ConditionalOnClass found required class 'com.fasterxml.jackson.databind.ObjectMapper' ; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition) CodecsAutoConfiguration.JacksonCodecConfiguration#jacksonCodecCustomizer matched: - @ConditionalOnBean (types: com.fasterxml.jackson.databind.ObjectMapper; SearchStrategy: all) found bean 'jacksonObjectMapper' (OnBeanCondition) DispatcherServletAutoConfiguration.DispatcherServletConfiguration matched: - @ConditionalOnClass found required class 'javax.servlet.ServletRegistration' ; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition) - Default DispatcherServlet did not find dispatcher servlet beans (DispatcherServletAutoConfiguration.DefaultDispatcherServletCondition) DispatcherServletAutoConfiguration.DispatcherServletRegistrationConfiguration matched: - @ConditionalOnClass found required class 'javax.servlet.ServletRegistration' ; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition) - DispatcherServlet Registration did not find servlet registration bean (DispatcherServletAutoConfiguration.DispatcherServletRegistrationCondition) ... ... ... |
Above logs tell why a particular bean was registered into spring context. This information is very useful when you debug the issues with auto configutation.
Similarily, everytime we add a new dependency to a Spring Boot project, Spring Boot auto-configuration automatically tries to configure the beans based on the dependency.
I hope that information discussed above will help you in future while debugging spring boot related issues.
Happy Learning !!