1、父项目依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
点进去我们发现spring-boot-starter-parent依赖的父项目:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
他才是真正来管理spring boot应用里的所有依赖版本,可以称为Spring boot的版本仲裁中心,以后我们导入依赖默认是不需要写版本的,没有在dependencies中管理的依赖我们依然要声明版本号。
2、场景启动器starter
我们拿web来说,在pom中导入依赖:
<!-- web 依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
spring-boot-starter-web点进去发现,已经帮我们导入了web mvc tomcat等所需要的依赖
spring-boot-starter : springboot场景启动器,帮我们导入场景所需的依赖。
其他场景例如:spring-boot-starter-redis、spring-boot-starter-batch等
springboot将所有功能场景都抽取出来,做成一个个的starter(启动器),只需要在项目中引入这些starter,就可以将相关场景的依赖导入进来。
我们看下主程序:
package com.learn;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class HelloWordMainApplication {
public static void main(String[] args) {
SpringApplication.run(HelloWordMainApplication.class,args);
}
}
@SpringBootApplication springboot应用标注在某个类上说明是主配置类,运行这个类的main方法来启动springboot应用。
我们点进去看下:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {@Filter(type = FilterType.CUSTOM,classes = {TypeExcludeFilter.class}), @Filter(ype = FilterType.CUSTOM,classes = {AutoConfigurationExcludeFilter.class})})
public @interface SpringBootApplication {
是个组合注解:
1、@SpringBootConfiguration :springboot的配置类
点进去发现也是个组合注解:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
@Configuration spring的注解,标注在配置类上,配置类也是容器中的一个组件@Component
2、@EnableAutoConfiguration :开启自动配置功能
springboot可以帮我们自动配置所需的配置,加上这个注解,是告诉springboot使配置生效。
点进去可以看到:
@AutoConfigurationPackage
@Import({EnableAutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
@AutoConfigurationPackage :自动配置包
点进去可以看到:
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
}
@Import spring底层注解,给容器导入一个组件,具体哪些组件,由Registrar.class这个类指定
看下底层代码:
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
AutoConfigurationPackages.register(registry, (new AutoConfigurationPackages.PackageImport(metadata)).getPackageName());
}
我们在这里打个断点,调试下:
我们可以总结出:@AutoConfigurationPackage 注解就是将主配置类(@SpringBootApplication标注的类)所在包及下边所有子包里边的所有组件扫描到spring容器中。
@Import({EnableAutoConfigurationImportSelector.class}) :给容器中导入组件
我们找到EnableAutoConfigurationImportSelector类的父类:
打个断点调试下:
可以看到,EnableAutoConfigurationImportSelector作用是将所有需要导入的组件以全类名的方式返回,@Import会给容器中导入非常多的自动配置类(xxxAutoConfiguration).
我们看下源码:
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
我们可以看到是在类路径下的 META-INF/spring.factories 中获取EnableAutoConfiguration的值
我们以webmvc的配置类为例,点进去看下:
可以看到,这些配置是不可以缺少的,只不过我们之前需要自动写的配置,springboot已经帮我们写好了。