一。springBoot项目的两个默认全局配置文件(一个是创建springboot项目时自动创建的,一个可以自动生成)
我们用Spring Initializer快速创建springBoot项目以后,在项目的resources目录下有一个static文件夹就是存放静态文件的目录,比如js,css image等,templates是存放模板引擎的,比如themlef。还有一个application.properties文件则是springBoot项目的全局配置文件。
springBoot还执行YAML格式的文件可以在resources下新建一个application.yml文件,它和applicatio.proerties相同都都已作为springBoot项目默认的全局配文件。
下面展示第一个springboot程序
//程序的主入口
@SpringBootApplication
public class HelloStartApplication {
public static void main(String[] args) {
SpringApplication.run(HelloStartApplication.class, args);
}
}
@Controller
@RequestMapping("/hello")
public class HelloController {
@RequestMapping("/springboot")
public void helloSpringBoot(){
System.out.println("hello world");
}
}
成功登录 ,可以发现没有任何的配置文件,springboot采用注解的方式,将我们可能用的的配置都提前配置到,放到包内,帮我们导入
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter‐web</artifactId>
</dependency>
</dependencies>
那springboot又是通过什么方式在启动项目的时候保证正常的运行呢?
看程序的主入口
//程序的主入口
@SpringBootApplication
public class HelloStartApplication {
public static void main(String[] args) {
SpringApplication.run(HelloStartApplication.class, args);
}
}
他有一个@SpringBootApplication注解,先说下我对注解的理解吧,我只说下容易理姐的大概的意思,其实加注解就是给被注解的类加功能,为什么这么说呢,被注解的类通过反射获取注解中的信息,获取到注解中的信息(属性值)以后,然后由专门的类或者方法做相应的操作。比如我们点进去@SpringBootApplication这个注解
@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 {
@AliasFor(
annotation = EnableAutoConfiguration.class
)
Class<?>[] exclude() default {
};
@AliasFor(
annotation = EnableAutoConfiguration.class
)
String[] excludeName() default {
};
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackages"
)
String[] scanBasePackages() default {
};
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackageClasses"
)
Class<?>[] scanBasePackageClasses() default {
};
@AliasFor(
annotation = ComponentScan.class,
attribute = "nameGenerator"
)
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
@AliasFor(
annotation = Configuration.class
)
boolean proxyBeanMethods() default true;
}
首先我们比较熟悉的@ComponentScan注解,自动扫描包,不去扫描一些客户自定义的注解
还有两个注解@SpringBootConfiguration,@EnableAutoConfiguration分别点进去一点一点分析:@SpringBootConfiguration中见到了@Configuration说明他就是一个配置类。
@Target({
ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
@AliasFor(
annotation = Configuration.class
)
boolean proxyBeanMethods() default true;
}
@EnableAutoConfiguration:除了元注解又有两个注解,一个是spring的原生注解@Import注解,一个是@AutoConfigurationPackage
@Target({
ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({
AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {
};
String[] excludeName() default {
};
}
@AutoConfigurationPackage:字面意思就是自动配置包,就是说装配哪个包路径下的类,点进去
@Target({
ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({
Registrar.class})
public @interface AutoConfigurationPackage {
String[] basePackages() default {
};
Class<?>[] basePackageClasses() default {
};
}
又是一个import注解,所以说到这里就要说些import注解的作用了,@import注解就是把注解中的值放到ioc容器中详情请参考
@Import注解的作用
我们点进去Registrar.class,debug一下代码
返现,registrar会将主入口的包的路径返回给也就是com.mystudy.hellostart所以这个注解的作用就是通过调用Registrar的registerBeanDefinitions方法,实现将类注入容器(这里得到的是包路径:com.mystudy.hellostart,也就是将包下的所有的类注入容器)
之前还提到了一个注解**@Import({AutoConfigurationImportSelector.class})**,我们分析一下,(分析的时候对照上面超链接中讲解@Import中的分析)
点开源码找到如下代码,是不是和超链接中的代码很像,然后就通过一些列的get ,set new 方法找到 代码二

public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}
//代码二
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
return configurations;
}
一路点进去,找到这里
发先,他是将META-INF/spring.factories配置文件中的jar 导入
总结:
springboot项目启动之所以不需要任何的配置,是因为他通过@SpringBootApplication 注解一步步定义了自动扫描的包路径,和需要用到的包,以前通过