Overview of Spring Boot
Build Anything with Spring Boot: Spring Boot is the starting point for building all Spring-based applications. Spring Boot is designed to get you up and running as quickly as possible, with minimal upfront configuration of Spring.
Here's a quote from the website, which probably means that Spring Boot is the starting point for all Spring-based projects.Spring Boot is designed to allow you to run the Spring application as quickly as possible and to minimize your profile.
What is Spring Boot
- It uses the concept of "Habits are better than configurations" (there are lots of configurations in your project, plus a custom configuration built in so you don't have to configure them manually) to get your project running quickly.
- It's not a new framework, but rather a default configuration of how many frameworks are used, like Maven integrating all jar packages, Spring Boot integrating all frameworks
What are the benefits of using Spring Boot
Reviewing our previous SMM projects, the construction process is cumbersome and requires:
- 1) Configure web.xml, load spring and spring mvc
- 2) Configure database connections, configure log files
- 3) Configurator reads profile and opens annotations
- 4) Configure mapper file
- .....
Developing a project with Spring Boot requires only a few configurations to build a Web project and IDEA to automatically generate the build
- Focus on: simple, fast and easy to build projects; no configuration integration of mainstream development frameworks; greatly improves development and deployment efficiency.
Spring Boot HelloWorld
Import dependent spring boot dependent dependencies
<?xml version="1.0" encoding="UTF-8"?> <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>cn.chenhao</groupId> <artifactId>springboot</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>jar</packaging> <name>springboot</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> <relativePath/> </parent> <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> </project>
Write main program
/** * @SpringBootApplication To label a main program class, this is a SpringBoot application */ @SpringBootApplication public class HelloWorldMainApplication { public static void main(String[] args) { //Spring Application Startup SpringApplication.run(HelloWorldMainApplication.class, args); } }
Write Controller, Service
@RestController public class HelloController { @RequestMapping("/hello") public String hello(){ return "Hello world"; } }
Run main program tests
Once you have packaged it into a jar package using the maven packaging command, use the command directly:
java -jar xxx.jar
Hello World Exploration
POM File
Parent Project
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> <relativePath/> </parent>
Its parent project is
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.0.1.RELEASE</version> <relativePath>../../spring-boot-dependencies</relativePath> </parent>
The parent project is really managing all dependent versions within the Spring Boot application: the version Arbitration Center for Spring Boot, so later imported dependencies do not require a version number by default.as follows
Many more version numbers are not captured
starter
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
Spring-boot-starter: spring boot scene launcher; helps import components on which the web module depends to function properly;
Spring Boot pulls out all the functional scenarios and makes them into starters one by one. All the dependencies of the related scenarios are imported into the project as long as these starters are introduced into the project.The launcher that imports any scene with what functionality you want.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency>
Adding a spring-boot-starter-web dependency automatically adds Tomcat and Spring MVC dependencies
spring-boot-starter-tomcat is also introduced in spring-boot-starter-web
Main Program Class (Main Entry Class)
@SpringBootApplication public class HelloWorldMainApplication { public static void main(String[] args) { //Spring Application Startup SpringApplication.run(HelloWorldMainApplication.class, args); } }
@SpringBootApplication
- The Spring Boot application is labeled on a class, indicating that this class is the main configuration class for SpringBoot, and SpringBoot should run the main method of this class to start the SpringBoot application.
The notes are defined as follows:
@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) public @interface SpringBootApplication {}
@SpringBootConfiguration
- Configuration Class for Spring Boot
- Label on a class to indicate that this is a configuration class for Spring Boot
The notes are defined as follows:
@Configuration public @interface SpringBootConfiguration {}
This is actually a Configuration configuration class, meaning that the HelloWorldMainApplication will eventually be registered in the Spring container
@EnableAutoConfiguration
- Turn on automatic configuration
- Previously using the information Spring needs to configure, Spring Boot helps to configure automatically;
- @EnableAutoConfiguration notifies SpringBoot to turn on auto-configuration so that it takes effect.
The notes are defined as follows:
@AutoConfigurationPackage @Import(EnableAutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration {}
@AutoConfigurationPackage
- Automatic configuration package annotations
@Import(AutoConfigurationPackages.Registrar.class) public @interface AutoConfigurationPackage {}
@Order(Ordered.HIGHEST_PRECEDENCE) static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports { @Override public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { //Default will scan@SpringBootApplication The package in which the labeled primary configuration class resides and all components under it register(registry, new PackageImport(metadata).getPackageName()); } @Override public Set<Object> determineImports(AnnotationMetadata metadata) { return Collections.<Object>singleton(new PackageImport(metadata)); } }
@Import(EnableAutoConfigurationImportSelector.class)
EnableAutoConfiguration ImportSelector: A selector that imports which components, returns all components that need to be imported as full class names, and these components are added to the container.
1 //EnableAutoConfigurationImportSelector The parent of: AutoConfigurationImportSelector 2 @Override 3 public String[] selectImports(AnnotationMetadata annotationMetadata) { 4 if (!isEnabled(annotationMetadata)) { 5 return NO_IMPORTS; 6 } 7 try { 8 AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader 9 .loadMetadata(this.beanClassLoader); 10 AnnotationAttributes attributes = getAttributes(annotationMetadata); 11 List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); 12 configurations = removeDuplicates(configurations); 13 configurations = sort(configurations, autoConfigurationMetadata); 14 Set<String> exclusions = getExclusions(annotationMetadata, attributes); 15 checkExcludedClasses(configurations, exclusions); 16 configurations.removeAll(exclusions); 17 configurations = filter(configurations, autoConfigurationMetadata); 18 fireAutoConfigurationImportEvents(configurations, exclusions); 19 return configurations.toArray(new String[configurations.size()]); 20 } 21 catch (IOException ex) { 22 throw new IllegalStateException(ex); 23 } 24 }
Let's focus on Line 11 List <String> configurations = getCandidateConfigurations (annotationMetadata, attributes); it will inject many automatic configuration classes (xxxAutoConfiguration) into the container, which is all the components needed to import this scene into the container and configure them.Let's follow up
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = SpringFactoriesLoader.loadFactoryNames( getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()); //... return configurations; } protected Class<?> getSpringFactoriesLoaderFactoryClass() { return EnableAutoConfiguration.class; } public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories"; public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) { String factoryClassName = factoryClass.getName(); try { //From Class Path META-INF/spring.factories Load all default auto-configuration classes in Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) : ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION)); List<String> result = new ArrayList<String>(); while (urls.hasMoreElements()) { URL url = urls.nextElement(); Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url)); //Obtain EnableAutoConfiguration All specified values,that is EnableAutoConfiguration.class Value of String factoryClassNames = properties.getProperty(factoryClassName); result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames))); } return result; } catch (IOException ex) { throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() + "] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex); } }
Finally, 96 AutoConfiguration classes were loaded and registered in the Spring container
The overall J2EE integration solution and automatic configuration are in spring-boot-autoconfigure-xxx.jar.In these auto-configuration classes, conditional annotations such as @ConditionalOnClass are used to determine if certain dependent packages have been imported, and the corresponding objects are registered with @Bean for auto-configuration.Later we'll have a separate article on automatic configuration