JDK:javac 1.8.0_144
MAVEN:Apache Maven 3.6.3
开发环境:IntelliJ IDEA 2019.3.3
Spring Boot:2.3.3
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.3.3.RELEASEversion>
parent>
<groupId>com.newbiegroupId>
<artifactId>spring-boot-01-helloworldartifactId>
<version>1.0-SNAPSHOTversion>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
dependencies>
package com.newbie;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用
**/
@SpringBootApplication
public class HelloWorldMainApplication {
public static void main(String[] args){
/**
* Spring应用的run方法,顾名思义是让Spring应用跑起来的方法
* 所需参数:要跑起来的主程序类的字节码 .class文件以及传进来的参数
**/
SpringApplication.run(HelloWorldMainApplication.class,args);
}
}
package com.newbie.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloWorldController {
@RequestMapping("/hello")
@ResponseBody
public String Hello(){
return "Hello World!";
}
}
看到这个标志就知道启动成功了,如果想换这个图标可以参考下面链接
更换启动日志输出
pom文件中加上插件,可在这里找到
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
然后再maven中打包,打包后在target目录下将jar复制出来
win+R cmd
cd到jar包所在目录,输入java - jar spring-boot-01-helloworld-1.0-SNAPSHOT.jar
,即可
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.3.3.RELEASEversion>
parent>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-dependenciesartifactId>
<version>2.3.3.RELEASEversion>
parent>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
spring-boot-starter-web:
package com.newbie;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
1. @SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用
**/
@SpringBootApplication
public class HelloWorldMainApplication {
public static void main(String[] args){
/**
* Spring应用的run方法,顾名思义是让Spring应用跑起来的方法
* 所需参数:要跑起来的主程序类的字节码 .class文件以及传进来的参数
**/
SpringApplication.run(HelloWorldMainApplication.class,args);
}
}
@SpringBootApplication:springboot应用,表明这个类是SpringBoot的主配置类
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
@SpringBootConfiguration:springboot配置,表明这是一个Spring Boot的配置类
- @Configuration:配置类上标注这个注解,配置类相当于原来的配置文件;
- @Component:配置类也是容器中的一个组件;
@EnableAutoConfiguration:开启自动配置功能;这里就是Spring Boot帮我们配置的重点;就是她将Spring原本繁琐的配置给予简化
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
@AutoConfigurationPackage:自动配置包;@Import({Registrar.class});Spring的底层@import,给容器导入一个组件;导入的组件在Registrar.class中;
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
Registrar() {
}
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0]));
/**
*(String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0])
计算得出下图
**/
}
public Set<Object> determineImports(AnnotationMetadata metadata) {
return Collections.singleton(new AutoConfigurationPackages.PackageImports(metadata));
}
}
@Import({Registrar.class});将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器里
@Import({AutoConfigurationImportSelector.class})
给容器导入那些组件?
AutoConfigurationImportSelector:导入哪些组件的选择器;将所有需要导入的组件以全类名的方式返回;然后被添加到容器中;
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
AnnotationAttributes attributes = getAttributes(annotationMetadata);
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = getConfigurationClassFilter().filter(configurations);
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
会给容器中导入非常多的自动配置类(xxxAutoConfiguration);就是给容器中导入这个场景需要的所有组件,并配置好这些组件;
SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,ClassLoader);
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
String factoryTypeName = factoryType.getName();
return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
if (result != null) {
return result;
} else {
try {
Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
LinkedMultiValueMap result = new LinkedMultiValueMap();
while(urls.hasMoreElements()) {
URL url = (URL)urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
Iterator var6 = properties.entrySet().iterator();
while(var6.hasNext()) {
Entry<?, ?> entry = (Entry)var6.next();
String factoryTypeName = ((String)entry.getKey()).trim();
String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
int var10 = var9.length;
for(int var11 = 0; var11 < var10; ++var11) {
String factoryImplementationName = var9[var11];
result.add(factoryTypeName, factoryImplementationName.trim());
}
}
}
cache.put(classLoader, result);
return result;
} catch (IOException var13) {
throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
}
}
}
getAutoConfigurationEntry–>getCandidateConfigurations–>loadFactoryNames–>loadSpringFactories–>(“META-INF/spring.factories”)
其实就是Spring Boot 在启动时从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作;
J2EE的整体整合解决方案和自动配置都在spring-boot-autoconfigure-2.3.3.RELEASE.jar
使用Spring Initializer