SpringBoot(1.5.6.RELEASE)源码解析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot(1.5.6.RELEASE)源码解析相关的知识,希望对你有一定的参考价值。

启动SpringBoot,需要在入口函数所在的类上添加@SpringBootApplication注解

1 @SpringBootApplication
2 public class Application {
3     public static void main(String[] args) {
4         SpringApplication.run(Application.class, args);
5     }
6 }

我们来看一下@SpringBootApplication注解

 1 @Target(ElementType.TYPE)
 2 @Retention(RetentionPolicy.RUNTIME)
 3 @Documented
 4 @Inherited
 5 @SpringBootConfiguration
 6 @EnableAutoConfiguration
 7 @ComponentScan(excludeFilters = {
 8         @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
 9         @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
10 public @interface SpringBootApplication {
11     @AliasFor(annotation = EnableAutoConfiguration.class, attribute = "exclude")
12     Class<?>[] exclude() default {};
13 
14     @AliasFor(annotation = EnableAutoConfiguration.class, attribute = "excludeName")
15     String[] excludeName() default {};
16 
17     @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
18     String[] scanBasePackages() default {};
19 
20     @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
21     Class<?>[] scanBasePackageClasses() default {};
22 }
1 @Target(ElementType.TYPE)
2 @Retention(RetentionPolicy.RUNTIME)
3 @Documented
4 @Configuration
5 public @interface SpringBootConfiguration {
6 }

从上面的代码可以看出@SpringBootApplication = @Configuration + @EnableAutoConfiguration + @ComponentScan

@Configuration注解,一般和@Bean注解搭配使用。使用这2个注解可以创建一个配置类,示例如下

 1 @Configuration
 2 public class Config {
 3     @Bean
 4     public People people() {
 5         People people = new People();
 6         people.setAge(26);
 7         people.setName("Dylan");
 8         people.setGender(1);
 9         return people;
10     }
11 }

可以替代xml配置文件里

1 <beans>
2     <bean id="people" class="com.dylan.java.beans.People">
3         <property name="age" value="26"></property>
4         <property name="name" value="Dylan"></property>
5         <property name="gender" value="1"></property>
6     </bean>
7 </beans>

@EnableAutoConfiguration注解自动载入应用程序所需要的所有Bean,这依赖于SpringBoot在类路径中的查找

 1 @SuppressWarnings("deprecation")
 2 @Target(ElementType.TYPE)
 3 @Retention(RetentionPolicy.RUNTIME)
 4 @Documented
 5 @Inherited
 6 @AutoConfigurationPackage
 7 @Import(EnableAutoConfigurationImportSelector.class)
 8 public @interface EnableAutoConfiguration {
 9     String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
10 
11     Class<?>[] exclude() default {};
12 
13     String[] excludeName() default {};
14 }

@EnableAutoConfiguration注解使用@Import注解导入EnableAutoConfigurationImportSelector类,此类继承了AutoConfigurationImportSelector类,而AutoConfigurationImportSelector类的selectImports方法就是关键所在

 1 @Override
 2 public String[] selectImports(AnnotationMetadata annotationMetadata) {
 3     if (!isEnabled(annotationMetadata)) {
 4         return NO_IMPORTS;
 5     }
 6     try {
 7         AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
 8                 .loadMetadata(this.beanClassLoader);
 9         AnnotationAttributes attributes = getAttributes(annotationMetadata);
10         List<String> configurations = getCandidateConfigurations(annotationMetadata,
11                 attributes);
12         configurations = removeDuplicates(configurations);
13         configurations = sort(configurations, autoConfigurationMetadata);
14         Set<String> exclusions = getExclusions(annotationMetadata, attributes);
15         checkExcludedClasses(configurations, exclusions);
16         configurations.removeAll(exclusions);
17         configurations = filter(configurations, autoConfigurationMetadata);
18         fireAutoConfigurationImportEvents(configurations, exclusions);
19         return configurations.toArray(new String[configurations.size()]);
20     }
21     catch (IOException ex) {
22         throw new IllegalStateException(ex);
23     }
24 }
1 protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
2             AnnotationAttributes attributes) {
3     List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
4             getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
5     Assert.notEmpty(configurations,
6             "No auto configuration classes found in META-INF/spring.factories. If you "
7                     + "are using a custom packaging, make sure that file is correct.");
8     return configurations;
9 }
1 protected Class<?> getSpringFactoriesLoaderFactoryClass() {
2     return EnableAutoConfiguration.class;
3 }

可以看出,该方法使用了Spring Core包的SpringFactoriesLoader类的loadFactoryNames方法,该方法会查询classpath下的JAR文件中包含的/META/spring.factories文件,从文件中读取配置文件名(这里是org.springframework.boot.autoconfigure.EnableAutoConfiguration)的属性,例如

在jar:file:/C:/Users/guiqingqing/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/1.5.6.RELEASE/spring-boot-autoconfigure-1.5.6.RELEASE.jar!/META-INF/spring.factories文件找到如下配置

# Auto Configure
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,org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoConfiguration,org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration,org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,org.springframework.boot.autoconfigure.security.SecurityFilterAutoConfiguration,org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,org.springframework.boot.autoconfigure.security.oauth2.OAuth2AutoConfiguration,org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,org.springframework.boot.autoconfigure.social.SocialWebAutoConfiguration,org.springframework.boot.autoconfigure.social.FacebookAutoConfiguration,org.springframework.boot.autoconfigure.social.LinkedInAutoConfiguration,org.springframework.boot.autoconfigure.social.TwitterAutoConfiguration,org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration,org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration,org.springframework.boot.autoconfigure.web.HttpEncodingAutoConfiguration,org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration,org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration,org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration,org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration,org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration,org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration,org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration

获取自动配置的类之后调用removeDuplicates方法先去除重复,然后调用sort方法进行排序,接下来调用getExclusions获取配置的exclude的类,比如@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}),然后这些exclude的类也会被排除

然后是调用filter方法,该方法决定哪些bean自动配置,哪些不配置。去classpath下的JAR文件中包含的/META/spring.factories文件里查询org.springframework.boot.autoconfigure.AutoConfigurationImportFilter对应的配置,这里找到的是org.springframework.boot.autoconfigure.condition.OnClassCondition,检查每个bean,看是否有@ConditionalOnClass注解,并且依赖的类不为空,则符合条件,那么需要自动配置,否则不配置。例如FreeMarkerAutoConfiguration类

1 @Configuration
2 @ConditionalOnClass({ freemarker.template.Configuration.class, FreeMarkerConfigurationFactory.class })
4 @AutoConfigureAfter(WebMvcAutoConfiguration.class)
5 @EnableConfigurationProperties(FreeMarkerProperties.class)
6 public class FreeMarkerAutoConfiguration {
7 }

该类的@ConditionalOnClass注解里有freemarker.template.Configuration.class和FreeMarkerConfigurationFactory.class类,如果classpath下能找到这2个类,那么就会自动加载FreeMarkerAutoConfiguration类

最后发布一个AutoConfigurationImportEvent事件

@ComponentScan注解会自动扫描指定包下的全部标有@Component(包括@Service、@Repository、@Controller等子注解)的类,并注册成bean

以上是关于SpringBoot(1.5.6.RELEASE)源码解析的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot(1.5.6.RELEASE)源码解析

spring boot版本对应

springboot 项目maven 打包错误

SpringBoot 01_HelloWorld

Maven parent.relativePath

RestTemplate Spring 启动中的 NullPointerException MediaType