SpringBoot(1.5.6.RELEASE)源码解析(一)

请尊重作者劳动成果,转载请标明原文链接:http://www.cnblogs.com/dylan-java/p/7450914.html

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

1 @SpringBootApplication2 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 @Documented4 @Configuration5 public @interface SpringBootConfiguration {6 }

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

@Configuration注解(可以理解为xml里面的<beans>标签),一般和@Bean注解(可以理解为xml里面的<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 Configureorg.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 @Configuration2 @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)源码解析(一)

相关文章:

你感兴趣的文章:

标签云: