它实现了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
方法一个关键方法:
@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {//配置有没有配置spring.boot.enableautoconfiguration开关,默认为true//如果为false,则不执行自动配置的功能,直接返回if (!isEnabled(annotationMetadata)) {return NO_IMPORTS;}//找spring-autoconfigure-metadata.properties中的元素AutoConfigurationMetadata autoConfigurationMetadata = https://www.huyubaike.com/biancheng/AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);//获取EnableAutoConfiguration注解中的属性AnnotationAttributes attributes = getAttributes(annotationMetadata);//获取工程下所有配置key为EnableAutoConfiguration的值,即IdGenerateConfiguration等类 。List
经验总结扩展阅读
- 比较高级的土味情话
- 大麦小麦和燕麦的区别
- 2023年2月15日是请佛吉日吗 2023年2月15日是请佛的黄道吉日吗
- 钨做灯丝的原因
- 雄蚕蛾泡酒方法
- 微信运动关注的人是什么意思
- 通大便的食物与水果
- 经典力学的奠基人是谁
- 中度贫血会头晕吗
- 养生堂维生素c的功效