SpringBoot自动配置的实现原理
一、运行原理
SpringBoot的运行是由注解@EnableAutoConfiguration提供的。
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import({EnableAutoConfigurationImportSelector.class}) public@interfaceEnableAutoConfiguration{ StringENABLED_OVERRIDE_PROPERTY="spring.boot.enableautoconfiguration"; Class>[]exclude()default{}; String[]excludeName()default{}; }
这里的关键功能是@Import注解。EnableAutoConfigurationImportSelector使用SpringFactoriesLoader.loadFactoryNames方法来扫描具有MEAT-INF/spring.factories文件的jar包(1.5版本以前使用EnableAutoConfigurationImportSelector类,1.5以后这个类废弃了使用的是AutoConfigurationImportSelector类),下面是spring-boot-autoconfigure-1.5.4.RELEASE.jar下的MEAT-INF中的spring.factories文件的部分内容。
#Initializers org.springframework.context.ApplicationContextInitializer=\ org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\ org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer #ApplicationListeners org.springframework.context.ApplicationListener=\ org.springframework.boot.autoconfigure.BackgroundPreinitializer #AutoConfigurationImportListeners org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\ org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener #AutoConfigurationImportFilters org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\ org.springframework.boot.autoconfigure.condition.OnClassCondition #AutoConfigure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\ org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\ org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\ org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\ org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\ org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\ org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\ org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
里面的类都是自动配置类,SpringBoot会根据这些自动配置类去自动配置环境。
下面我们就自动动手写一个starter。
二、自定义Starter
首先先介绍几个条件注解。
- @ConditionalOnBean:当容器里有指定的Bean为true
- @ConditionalOnClass:当类路径下有指定的类为true
- @ConditionalOnMissingBean:当容器里没有指定的Bean为true
- @ConditionalOnProperty:指定的数据是否有指定的值
- ...
了解了条件注解后,我们开始自定义Starter。
1、在自定义Starter之前先要在Maven中填写依赖。
4.0.0 cn.miaolovezhen spring-boot-starter-test 0.0.1-SNAPSHOT jar spring-boot-starter-test DemoprojectforSpringBoot org.springframework.boot spring-boot-starter-parent 1.5.6.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-autoconfigure 1.5.4.RELEASE
2、完成TestProperties类,这个类定义了默认的属性值,如该类中,只有一个属性值msg,默认为world。@ConfigurationProperties注解会定义一个匹配,如果想修改属性值,可以在application.properties中使用“匹配.属性=修改的值”进行修改。如test.msg=tan
@ConfigurationProperties(prefix="test") publicclassTestProperties{ privatestaticfinalStringMSG="springboot"; privateStringmsg=MSG; publicStringgetMsg(){ returnmsg; } publicvoidsetMsg(Stringmsg){ this.msg=msg; } }
3、完成服务类。服务类是指主要的功能类,如果没有SpringBoot,这些服务类在Spring中都是需要自己去配置生成的。如SpringMVC中的DispatcherServlet、Mybatis的DataSource等。
publicclassTestService{ privateStringmsg; publicStringsayHello(){ return"Hello"+msg; } publicStringgetMsg(){ returnmsg; } publicvoidsetMsg(Stringmsg){ this.msg=msg; } }
4、完成自动配置类。自动配置类主要作用是SpringBoot的配置核心,它会写在MEAT-INF/spring.factories中,告知SpringBoot在启动时去读取该类并根据该类的规则进行配置。
- @EnableConfigurationProperties注解根据TestProperties类开启属性注入,允许在application.properties修改里面的属性值。
- @ConditionOnClass会检测是否存在TestService类
- @ConditionOnProperty类会查看是否开启该自动配置。默认开启(true)。
- @ConditionOnMissingBean会检测容器中是否有TestService类的对象,如果没有则生成一个。
@Configuration @EnableConfigurationProperties(TestProperties.class) @ConditionalOnClass(TestService.class) @ConditionalOnProperty(prefix="test",value="enabled",matchIfMissing=true) publicclassTestServiceAutoConfiguration{ @Autowired TestPropertiestestProperties; @Bean @ConditionalOnMissingBean(TestService.class) publicTestServicetestService(){ TestServicetestService=newTestService(); testService.setMsg(testProperties.getMsg()); returntestService; } }
5、最后一步,不要忘记在在MEAT-INF文件夹中创建spring.factories文件。内容很简单,告诉SpringBoot去读取TestServiceAutoConfiguration类。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ cn.miaolovezhen.TestServiceAutoConfiguration
好啦,搞定!下面可以使用maveninstall命令把starter存到本地,其他SpringBoot项目需要使用这个starter,直接导入就可以啦。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。