当前位置:首页 > 经验 >

springboot的starter原理(springboot starter核心组件)

来源:原点资讯(www.yd166.com)时间:2022-10-29 11:58:07作者:YD166手机阅读>>

该项目里面包含:pom.xml、application.properties、Application 和 TestRunner 文件。

先看看pom.xml文件

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <version>1.3.1</version> <groupId>com.sue</groupId> <artifactId>spring-boot-id-generate-test</artifactId> <name>spring-boot-id-generate-test</name> <dependencies> <dependency> <groupId>com.sue</groupId> <artifactId>id-generate-spring-boot-starter</artifactId> <version>1.3.1</version> </dependency> </dependencies> </project>

由于只测试刚刚定义的id生成功能,所以只引入的id-generate-spring-boot-starter jar包。

application.properties配置资源文件

sue.workId=123

只有一行配置,因为我们的IdProperties中目前只需要这一个参数。

Application是测试程序启动类

@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }

很简单,就是一个普通的springboot启动类

TestRunner是我们的测试类

@Component public class TestRunner implements ApplicationRunner { @Autowired private IdGenerateService idGenerateService; public void run(ApplicationArguments args) throws Exception { Long sysNo = idGenerateService.generate(); System.out.println(sysNo); } }

它实现了ApplicationRunner接口,所以在springboot启动的时候会调用该类的run方法。

好了,所有自定义starter的代码和测试代码都已经就绪。接下,运行一下Application类的main方法。

运行结果:

176

完美,验证成功了。

接下来,我们分析一下starter的底层实现原理。

4 starter的底层原理是什么?

通过上面编写自己的starter的例子,相信大家对starter的认识更进一步了,现在跟大家一起看看starter的底层是如何实现的。

id-generate-starter.jar其实是一个空项目,依赖于id-generate-autoconfiguration.jar。

id-generate-starter.jar是一个入口,我们给他取一个更优雅的名字:门面模式,其他业务系统想引入相应的功能,必须要通过这个门面。

我们重点分析一下 id-generate-autoconfiguration.jar

该jar包核心内容是:IdGenerateConfiguration,这个配置类中创建了IdGenerateService对象,IdGenerateService是我们所需要自动配置的具体功能。

接下来一个最重要的问题:IdGenerateConfiguration为什么会自动加载的呢?

还记得我们定义的spring.factories文件不?

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.sue.IdGenerateAutoConfiguration

它里面只包含一行配置,其中key是EnableAutoConfiguration,value是IdGenerateAutoConfiguration。

要搞明白这个过程,要从Application类的@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 {}; }

从上面可以看出该注解里面包含了@EnableAutoConfiguration注解。

@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 {}; }

@EnableAutoConfiguration注解会引入AutoConfigurationImportSelector类。

该类的selectImports方法一个关键方法:

@Override public String[] selectImports(AnnotationMetadata annotationMetadata) { //配置有没有配置spring.boot.enableautoconfiguration开关,默认为true //如果为false,则不执行自动配置的功能,直接返回 if (!isEnabled(annotationMetadata)) { return NO_IMPORTS; } //找spring-autoconfigure-metadata.properties中的元素 AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader .loadMetadata(this.beanClassLoader); //获取EnableAutoConfiguration注解中的属性 AnnotationAttributes attributes = getAttributes(annotationMetadata); //获取工程下所有配置key为EnableAutoConfiguration的值,即IdGenerateConfiguration等类。 List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); //删除重复的值 configurations = removeDuplicates(configurations); //获取需要排除的规则列表 Set<String> exclusions = getExclusions(annotationMetadata, attributes); //检查 checkExcludedClasses(configurations, exclusions); //删除需要排除的值 configurations.removeAll(exclusions); //根据配置文件中配置的开关,过滤一部分不满足条件的值 configurations = filter(configurations, autoConfigurationMetadata); fireAutoConfigurationImportEvents(configurations, exclusions); return StringUtils.toStringArray(configurations); }

这里就是starter能够自动配置的秘密。

此外,有些朋友看其他人定义的springboot starter可能会有疑惑。

先看看druid-spring-boot-starter

springboot的starter原理,springboot starter核心组件(9)

alibaba定义的druid-spring-boot-starter只有xxx-spring-boot-starter.jar文件,而没有xxx-spring-boot-autoconfigure.jar文件。

再看看spring-boot-starter-jdbc:

springboot的starter原理,springboot starter核心组件(10)

更神奇的是这个文件中连pom.xml都没有,一脸懵逼。。。。。。。

是不是我讲错了?

答:其实没有。

SpringBoot的原则是约定优于配置。

从spring-boot-starter-jdbc内部空实现来看,它的约定是要把xxx-spring-boot-starter.jar和xxx-spring-boot-autoconfigure.jar区分开的。个人认为,alibaba定义得并不好,没有遵照springboot的约定,虽然功能不受影响。(这个地方欢迎一起探讨一下)

而springboot自己定义的spring-boot-starter-jdbc为什么连pom.xml文件也没有呢?

它不需要依赖xxx-spring-boot-autoconfigure.jar文件吗?

因为springboot把所有的自动配置的类都统一放到spring-boot-autoconfigure.jar下面了:

springboot的starter原理,springboot starter核心组件(11)

spring.factories文件内容如下:

springboot的starter原理,springboot starter核心组件(12)

栏目热文

mybatis作用及特点(mybatis优点有哪些)

mybatis作用及特点(mybatis优点有哪些)

a、MyBatis 把 sql 语句从 Java 源程序中独立出来,放在单独的 XML 文件中编写,给程序的维护带来了很...

2022-10-29 11:45:02查看全文 >>

mybatis工作原理分析(mybatis工作原理及项目操作配置)

mybatis工作原理分析(mybatis工作原理及项目操作配置)

前言:mybatis是最近几年比较流行的操作数据库框架了,平时都只知道怎么去配置,怎么去用它,那你们知道它是如何实现的吗...

2022-10-29 12:11:32查看全文 >>

mybatis简介(mybatis的详细讲解)

mybatis简介(mybatis的详细讲解)

一. mybatisMyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache so...

2022-10-29 11:28:39查看全文 >>

mybatis面试题(java面试必背八股文)

mybatis面试题(java面试必背八股文)

点击上方"java全栈技术"关注,每天学习一个java知识点1. #{}和${}的区别是什么?#{}是预编译处理,${}...

2022-10-29 11:56:17查看全文 >>

mybatis详细讲解(mybatis操作步骤)

mybatis详细讲解(mybatis操作步骤)

废话不多说,直接进入文章。我们在使用Mybatis的时候,会在xml中编写SQL语句。如图:那么,MyBatis底层是如...

2022-10-29 11:57:34查看全文 >>

mybatisplus 代码生成器(mybatisplus代码生成器模板)

mybatisplus 代码生成器(mybatisplus代码生成器模板)

简介: 代码生成器,也叫逆向工程,是根据数据库里的表结构,自动生成对应的实体类、映射文件和接口。代码生成器,也叫逆向工程...

2022-10-29 12:13:45查看全文 >>

springboot菜鸟教程(菜鸟教程spring boot)

springboot菜鸟教程(菜鸟教程spring boot)

- 一、SpringBoot的starter简介 -1.1 什么是starter(场景启动器)在SpringBoot出现...

2022-10-29 12:02:31查看全文 >>

mybatis详解(mybatis简单示例)

mybatis详解(mybatis简单示例)

MyBatis缓存框架与事务详解一、缓存的概念1.1什么是缓存 存在内存中的临时数据。 将用户经常查询的数据放在缓存(内...

2022-10-29 11:50:24查看全文 >>

简单的灯笼怎么叠(叠小灯笼方法)

简单的灯笼怎么叠(叠小灯笼方法)

过年啦,家家户户挂灯笼,今天教大家折一款樱花灯笼,颜值非常高,中间是一个樱花球,主要是做法超级简单。先剪一张圆形的纸,直...

2022-10-29 11:35:53查看全文 >>

一张纸叠灯笼(一张纸折灯笼大全)

一张纸叠灯笼(一张纸折灯笼大全)

树姐姐昨天发布的3款简单的灯笼很受到大家的欢迎,我好开心哦。离中秋越来越近了,今天树姐姐再给大家分享一款组合型的中式手提...

2022-10-29 12:02:02查看全文 >>

文档排行