Spring Boot自定义starter

一、Spring Boot核心注解

1.核心注解:

a.@SpringBootConfiguration:包含了@Configuration,实现配置类

b.@EnableAutoConfiguration:使用Import引入了AutoConfigurationImportSelector类,而AutoConfigurationImportSelector类通过SpringFactortisLoader加载了所有jar包的MATE-INF文件夹下面的spring.factories文件,spring.factories包含了所有需要装配的XXXConfiguration类的全限定名

c.@ComponentScan:指定扫描范围

2.这几个注解完成了自动装配功能,即把bean注入到Spring容器里

3.SpringBootApplication 启动类,组合了这3个注解,避免开发者一个个去添加

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
    Class<?>[] exclude() default {};

    String[] excludeName() default {};

    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackages"
    )
    String[] scanBasePackages() default {};

    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackageClasses"
    )
    Class<?>[] scanBasePackageClasses() default {};
}

 

4.通过配置类注解,实现自定义starter

a.提供注解,加到我们自己的配置类上

b.提供spring.factories文件,包含了配置类的全限定名

c.把配置类和spring.factories文件打包为一个启动器starter

d.使用starter包的程序启动时,加载starter包里的spring.factories文件,然后通过反射,实例化文件里面的类,最后注入到Spring容器中

 

二、官方starter

  • spring-boot-starter-web//spring MVC相关
  • spring-boot-starter-aop //切面编程相关
  • spring-boot-starter-cache //缓存相关

 

 

三、自定义starter

1.创建自定义starter

a.命名规则:aaa-spring-boot-starter

b.新建一个配置类,加上注解@ConfigurationPropertie:结合相关xxxProperties类来绑定相关的配置

c.新建一个服务类,编写服务,使用配置类

d.新建一个组件类,把服务注入组件,加上注解 @Configuration :指定这个类是一个配置类

e. SpringBoot读取自动配置是在META-INF的spring.factories文件中,所以我们还要将我们的自动配置类写入其中

 

 

2.使用自定义starter

a.引入依赖

b.application.properties 配置中加上配置

c.调用starter里的服务接口

 

3.Spring Boot 在启动的时候,按照约定去读取 Spring Boot Starter 的配置信息,再根据配置信息对资源进行初始化,并注入到 Spring 容器中

 

 

四、Spring Boot启动流程

1.实例化SpringApplication对象

SpringApplication springApplication = new SpringApplication(A.class);
// 构造函数里调用初始化方法
this.initialize(sources);

private void initialize(Object[] sources) {
    if (sources != null && sources.length > 0) {
        this.sources.addAll(Arrays.asList(sources));
    }

    // 确定web应用类型
    this.webEnvironment = this.deduceWebEnvironment();
    // 从类路径下找到META-INF/spring.factories配置的所有ApplicationContextInitializer,然后再保存起来
    this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
    // 从类路径下找到ETA-INF/spring.factories配置的所有ApplicationListener
    this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
    // 从多个配置类中找到有main方法的主配置类
    this.mainApplicationClass = this.deduceMainApplicationClass();
}

 

2.调用run()方法

springApplication.run(args);
public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        FailureAnalyzers analyzers = null;
        this.configureHeadlessProperty();
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        listeners.started();

        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
            Banner printedBanner = this.printBanner(environment);

// 创建ApplicationContext,决定创建web的ioc还是普通的ioc context = this.createApplicationContext(); new FailureAnalyzers(context); this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);

// 刷新容器,ioc容器初始化(如果是web应用还会创建嵌入式的Tomcat),这个就是扫描,创建,加载所有组件的地方,(配置类,组件,自动配置) this.refreshContext(context); this.afterRefresh(context, applicationArguments); listeners.finished(context, (Throwable)null); stopWatch.stop(); if (this.logStartupInfo) { (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch); } return context; } catch (Throwable var9) { this.handleRunFailure(context, listeners, (FailureAnalyzers)analyzers, var9); throw new IllegalStateException(var9); } }

 

 

 

 

 

 

 

参考:

https://blog.csdn.net/java_fenxiang/article/details/89718367

https://blog.csdn.net/qq_27828675/article/details/115700493

https://www.jb51.net/article/169172.htm

 

posted @ 2022-06-01 12:06  牧云文仔  阅读(511)  评论(0编辑  收藏  举报