SpringBoot学习笔记---启动原理

一。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 注解一步步定义了自动扫描的包路径,和需要用到的包,以前通过

猜你喜欢

转载自blog.csdn.net/Insect_boy/article/details/111223725