Anotación @SpringBootApplication de Spring Boot
La anotación Spring Boot @SpringBootApplicationse utiliza para marcar una clase de configuración que declara uno o más @Beanmétodos y también activa auto-configurationy escanea componentes. Es lo mismo que declarar una clase con las anotaciones @Configuration , @EnableAutoConfiguration y @ComponentScan .
Clase SpringApplication de Spring Boot
La clase Spring Boot SpringApplication se utiliza para iniciar y ejecutar una aplicación Spring desde un método principal de Java. Esta clase crea automáticamente la aplicación ApplicationContextdesde la ruta de clase, escanea las clases de configuración y ejecuta la aplicación. Esta clase es muy útil para ejecutar aplicaciones Spring MVC o Spring REST con Spring Boot.
Ejemplo de SpringBootApplication y SpringApplication
En el último tutorial sobre Spring RestController , creamos un servicio web Spring RESTful y lo implementamos en Tomcat. Tuvimos que crear un web.xmlarchivo de contexto Spring. También tuvimos que agregar manualmente las dependencias Spring MVC y administrar sus versiones. Aquí cambiaremos el proyecto para que se ejecute como una aplicación Spring Boot y nos desharemos de los archivos de configuración. Esto ayudará en la prueba rápida de la lógica de nuestra aplicación porque no tendremos que compilar e implementar manualmente el proyecto en el servidor Tomcat externo.
Debes consultar el proyecto existente desde nuestro repositorio de GitHub . En las siguientes secciones realizaremos los cambios necesarios en los archivos del proyecto.
La siguiente imagen muestra la estructura final de nuestro proyecto.
Cómo agregar dependencias de Maven a Spring Boot
El primer paso es limpiar pom.xmlel archivo y configurarlo para Spring Boot. Dado que es un servicio web REST, solo necesitamos spring-boot-starter-webdependencias. Sin embargo, tendremos que mantener las dependencias JAXB porque estamos ejecutando Java 10 y también queremos admitir solicitudes y respuestas XML. También tendremos que agregar spring-boot-maven-pluginun complemento que nos permita ejecutar nuestra aplicación Java simple como una aplicación Spring Boot. Aquí está nuestro archivo pom.xml actualizado.
project xmlns_xsi="https://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"modelVersion4.0.0/modelVersiongroupIdSpring-RestController/groupIdartifactIdSpring-RestController/artifactIdversion0.0.1-SNAPSHOT/versionpackagingwar/packagingparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.0.2.RELEASE/versionrelativePath / !-- lookup parent from repository --/parentpropertiesproject.build.sourceEncodingUTF-8/project.build.sourceEncodingproject.reporting.outputEncodingUTF-8/project.reporting.outputEncodingjava.version10/java.version/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!-- JAXB for XML Response needed to explicitly define from Java 9 onwards --dependencygroupIdjavax.xml.bind/groupIdartifactIdjaxb-api/artifactId/dependencydependencygroupIdorg.glassfish.jaxb/groupIdartifactIdjaxb-runtime/artifactIdversion2.3.0/versionscoperuntime/scope/dependencydependencygroupIdjavax.activation/groupIdartifactIdjavax.activation-api/artifactIdversion1.2.0/version/dependency/dependenciesbuild!-- added to remove Version from WAR file --finalName${project.artifactId}/finalNamepluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/plugin/plugins/build/project
Podemos eliminar el directorio WebContent o dejarlo como está, no será utilizado por nuestra aplicación Spring Boot.
Clase de aplicación Spring Boot
Ahora tenemos que crear una clase Java con el método principal, marcarla con @SpringBootApplicationuna anotación e invocar SpringApplication.run()el método.
package com.journaldev.spring;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class SpringBootRestApplication {public static void main(String[] args) {SpringApplication.run(SpringBootRestApplication.class, args);}}
Simplemente ejecute la clase como una aplicación Java y obtendrá el siguiente resultado. He eliminado algunos registradores que no nos interesan aquí. La aplicación no se cerrará y esperará las solicitudes del cliente.
2018-06-18 14:33:51.276 INFO 3830 --- [ main] c.j.spring.SpringBootRestApplication : Starting SpringBootRestApplication on pankaj with PID 3830 (/Users/pankaj/Documents/eclipse-jee-workspace/Spring-RestController/target/classes started by pankaj in /Users/pankaj/Documents/eclipse-jee-workspace/Spring-RestController)2018-06-18 14:33:51.280 INFO 3830 --- [ main] c.j.spring.SpringBootRestApplication : No active profile set, falling back to default profiles: default2018-06-18 14:33:51.332 INFO 3830 --- [ main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@38467116: startup date [Mon Jun 18 14:33:51 IST 2018]; root of context hierarchy2018-06-18 14:33:52.311 INFO 3830 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)2018-06-18 14:33:52.344 INFO 3830 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]2018-06-18 14:33:52.344 INFO 3830 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.312018-06-18 14:33:52.453 INFO 3830 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext2018-06-18 14:33:52.453 INFO 3830 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1127 ms2018-06-18 14:33:52.564 INFO 3830 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]2018-06-18 14:33:52.927 INFO 3830 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/rest/employee/get/{id}],methods=[GET]}" onto public com.journaldev.spring.model.Employee com.journaldev.spring.controller.EmployeeRestController.getEmployeeByID(int)2018-06-18 14:33:52.928 INFO 3830 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/rest/employee/getAll],methods=[GET]}" onto public java.util.Listcom.journaldev.spring.model.Employee com.journaldev.spring.controller.EmployeeRestController.getAllEmployees()2018-06-18 14:33:52.929 INFO 3830 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/rest/employee/create],methods=[POST]}" onto public com.journaldev.spring.model.Employee com.journaldev.spring.controller.EmployeeRestController.createEmployee(com.journaldev.spring.model.Employee)2018-06-18 14:33:52.929 INFO 3830 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/rest/employee/search/{name}],methods=[GET]}" onto public com.journaldev.spring.model.Employee com.journaldev.spring.controller.EmployeeRestController.getEmployeeByName(java.lang.String)2018-06-18 14:33:52.929 INFO 3830 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/rest/employee/delete/{id}],methods=[DELETE]}" onto public com.journaldev.spring.model.Employee com.journaldev.spring.controller.EmployeeRestController.deleteEmployeeByID(int)2018-06-18 14:33:53.079 INFO 3830 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup2018-06-18 14:33:53.118 INFO 3830 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''2018-06-18 14:33:53.124 INFO 3830 --- [ main] c.j.spring.SpringBootRestApplication : Started SpringBootRestApplication in 2.204 seconds (JVM running for 2.633)
Algunos puntos importantes que podemos deducir de los registros:
- El ID del proceso de aplicación de Spring Boot es 3830.
- La aplicación Spring Boot está iniciando Tomcat en el puerto 8080.
- Nuestra ruta de contexto de aplicación es “”. Esto significa que al invocar nuestras API no necesitamos proporcionar el contexto del servlet.
- El registrador imprime todas las API que están configuradas, ver mensajes
Mapped "{[/rest/employee/get/{id}],methods=[GET]}", etc.
La siguiente imagen muestra un ejemplo de invocación de las API expuestas por nuestra aplicación Spring Boot.
Paquetes básicos de escaneo de la aplicación SpringBoot
De forma predeterminada, SpringApplication escanea el paquete de la clase de configuración y todos sus subpaquetes. Por lo tanto, si nuestra SpringBootRestApplicationclase está en com.journaldev.spring.mainel paquete, no escaneará com.journaldev.spring.controllerel paquete. Podemos solucionar esta situación utilizando la propiedad scanBasePackages de SpringBootApplication.
@SpringBootApplication(scanBasePackages="com.journaldev.spring")public class SpringBootRestApplication {}
Beans autoconfigurados de Spring Boot
Dado que Spring Boot ofrece configuración automática, hay muchos beans que se configuran mediante este. Podemos obtener una lista de estos beans mediante el siguiente fragmento de código.
ApplicationContext ctx = SpringApplication.run(SpringBootRestApplication.class, args);String[] beans = ctx.getBeanDefinitionNames();for(String s : beans) System.out.println(s);
A continuación se muestra la lista de beans configurados por nuestra aplicación de arranque de primavera.
org.springframework.context.annotation.internalConfigurationAnnotationProcessororg.springframework.context.annotation.internalAutowiredAnnotationProcessororg.springframework.context.annotation.internalRequiredAnnotationProcessororg.springframework.context.annotation.internalCommonAnnotationProcessororg.springframework.context.event.internalEventListenerProcessororg.springframework.context.event.internalEventListenerFactoryspringBootRestApplicationorg.springframework.boot.autoconfigure.internalCachingMetadataReaderFactoryemployeeRestControlleremployeeRepositoryorg.springframework.boot.autoconfigure.AutoConfigurationPackagesorg.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfigurationorg.springframework.boot.autoconfigure.condition.BeanTypeRegistrypropertySourcesPlaceholderConfigurerorg.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration$TomcatWebSocketConfigurationwebsocketContainerCustomizerorg.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfigurationorg.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration$EmbeddedTomcattomcatServletWebServerFactoryorg.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfigurationservletWebServerFactoryCustomizertomcatServletWebServerFactoryCustomizerserver-org.springframework.boot.autoconfigure.web.ServerPropertiesorg.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessororg.springframework.boot.context.properties.ConfigurationBeanFactoryMetadatawebServerFactoryCustomizerBeanPostProcessorerrorPageRegistrarBeanPostProcessororg.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration$DispatcherServletConfigurationdispatcherServletmainDispatcherServletPathProviderspring.mvc-org.springframework.boot.autoconfigure.web.servlet.WebMvcPropertiesorg.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration$DispatcherServletRegistrationConfigurationdispatcherServletRegistrationorg.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfigurationorg.springframework.boot.autoconfigure.validation.ValidationAutoConfigurationdefaultValidatormethodValidationPostProcessororg.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfigurationerrorbeanNameViewResolverorg.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration$DefaultErrorViewResolverConfigurationconventionErrorViewResolverorg.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfigurationerrorAttributesbasicErrorControllererrorPageCustomizerpreserveErrorControllerTargetClassPostProcessorspring.resources-org.springframework.boot.autoconfigure.web.ResourcePropertiesorg.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter$FaviconConfigurationfaviconHandlerMappingfaviconRequestHandlerorg.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfigurationrequestMappingHandlerAdapterrequestMappingHandlerMappingmvcConversionServicemvcValidatormvcContentNegotiationManagermvcPathMatchermvcUrlPathHelperviewControllerHandlerMappingbeanNameHandlerMappingresourceHandlerMappingmvcResourceUrlProviderdefaultServletHandlerMappingmvcUriComponentsContributorhttpRequestHandlerAdaptersimpleControllerHandlerAdapterhandlerExceptionResolvermvcViewResolvermvcHandlerMappingIntrospectororg.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapterdefaultViewResolverviewResolverwelcomePageHandlerMappingrequestContextFilterorg.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfigurationhiddenHttpMethodFilterhttpPutFormContentFilterorg.springframework.boot.autoconfigure.jmx.JmxAutoConfigurationmbeanExporterobjectNamingStrategymbeanServerorg.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfigurationorg.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$Jackson2ObjectMapperBuilderCustomizerConfigurationstandardJacksonObjectMapperBuilderCustomizerspring.jackson-org.springframework.boot.autoconfigure.jackson.JacksonPropertiesorg.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperBuilderConfigurationjacksonObjectMapperBuilderorg.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$ParameterNamesModuleConfigurationparameterNamesModuleorg.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperConfigurationjacksonObjectMapperorg.springframework.boot.autoconfigure.jackson.JacksonAutoConfigurationjsonComponentModuleorg.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration$StringHttpMessageConverterConfigurationstringHttpMessageConverterspring.http.encoding-org.springframework.boot.autoconfigure.http.HttpEncodingPropertiesorg.springframework.boot.autoconfigure.http.JacksonHttpMessageConvertersConfiguration$MappingJackson2HttpMessageConverterConfigurationmappingJackson2HttpMessageConverterorg.springframework.boot.autoconfigure.http.JacksonHttpMessageConvertersConfigurationorg.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfigurationmessageConvertersorg.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration$JacksonCodecConfigurationjacksonCodecCustomizerorg.springframework.boot.autoconfigure.http.codec.CodecsAutoConfigurationorg.springframework.boot.autoconfigure.info.ProjectInfoAutoConfigurationspring.info-org.springframework.boot.autoconfigure.info.ProjectInfoPropertiesorg.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfigurationspring.security-org.springframework.boot.autoconfigure.security.SecurityPropertiesorg.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfigurationrestTemplateBuilderorg.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration$TomcatWebServerFactoryCustomizerConfigurationtomcatWebServerFactoryCustomizerorg.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfigurationorg.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfigurationcharacterEncodingFilterlocaleCharsetMappingsCustomizerorg.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfigurationmultipartConfigElementmultipartResolverspring.servlet.multipart-org.springframework.boot.autoconfigure.web.servlet.MultipartProperties
Esa es una lista enorme, hay muchos beans configurados automáticamente que no estamos usando. Podemos optimizar nuestra aplicación Spring Boot desactivándolos mediante @SpringBootApplication exclude o excludeNamela propiedad. El siguiente fragmento de código deshabilitará la configuración automática de JMX y Multipart.
@SpringBootApplication(scanBasePackages = "com.journaldev.spring", exclude = {org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration.class, org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration.class })public class SpringBootRestApplication {}
Tenga en cuenta que si intentamos excluir cualquier clase que no sea de configuración automática, obtendremos un error y nuestra aplicación no se iniciará.
@SpringBootApplication(scanBasePackages = "com.journaldev.spring", exclude = {com.journaldev.spring.controller.EmployeeRestController.class })public class SpringBootRestApplication {}
El fragmento de código anterior arrojará el siguiente error:
2018-06-18 15:10:43.602 ERROR 3899 --- [main] o.s.boot.SpringApplication: Application run failedjava.lang.IllegalStateException: The following classes could not be excluded because they are not auto-configuration classes:- com.journaldev.spring.controller.EmployeeRestController
Eso es todo para SpringBootApplicationla anotación y SpringApplicationel ejemplo.
Puedes descargar el proyecto final desde nuestro Repositorio de GitHub .