Spring Boot起步依赖源码分析(一)
2016-12-21 23:44
603 查看
这里我们搭建一个简单的spring boot web应用
maven依赖
pom.xml
下面是一个简单的spring boot的启动配置类,需要关注的有只有两点@EnableAutoConfiguration注解和SpringApplication类
(如果你还没有使用过搭建过spring boot的开发环境,请先查阅我的上篇博客3分钟快速搭建Spring Boot开发环境)
1、程序入口
这是一个静态方法创建了一个SpringApplication对象,注入了入口函数的Class(作用:获取@EnableAutoConfiguration注解)和args,并调用了SpringApplication对象的run()方法
2、构造初始化
这里的mainApplicationClass就是我们自己写的MainInit类
3、SpringApplication.run()
看到这里,如果追过spring源码的老司机应该就很熟悉,这里初始化了spring,afterRefresh(context, applicationArguments)最终会调用AbstractApplicationContext.refresh()方法中,在这里会构建spring的ioc容器
4、构建ioc容器
这里构建了IOC容器,因为在pom.xml中我们加入了spring mvc的依赖,这里spring boot会自动把spring mvc所需要的bean注册到IOC容器中,这里我们不看IOC容器是如果构建的,只关心spring boot 是如何自动把spring mvc所需要的bean注册到IOC容器中的。还记得@EnableAutoConfiguration注解吗?(如果忘了,请翻到博客头部回忆一下)下面是EnableAutoConfiguration注解的源码
主要看EnableAutoConfigurationImportSelector这个类,这个类会导入spring boot中的一个配置文件,方法如下:
这个方法会导入spring-boot-autoconfigure包下META-INF/spring.factories配置文件
spring.factories
通过getCandidateConfigurations方法,会把配置文件中org.springframework.boot.autoconfigure.EnableAutoConfiguration=后的所有配置类的全类名信息读取到一个List集合中,这里看到一个比较亲切的名字org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration看类名就能猜到这应该就是我们需要找东西了。2016年12月21日23:43:06 时间不早,(~﹃~)~zZ 下次再战,预知后事如何,请听下回分解
maven依赖
pom.xml
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.2.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
下面是一个简单的spring boot的启动配置类,需要关注的有只有两点@EnableAutoConfiguration注解和SpringApplication类
(如果你还没有使用过搭建过spring boot的开发环境,请先查阅我的上篇博客3分钟快速搭建Spring Boot开发环境)
@EnableAutoConfiguration public class MainInit { public static void main(String[] args) throws Exception { SpringApplication.run(MainInit.class, args); } }
1、程序入口
public static ConfigurableApplicationContext run(Object[] sources, String[] args) { return new SpringApplication(sources).run(args); }
这是一个静态方法创建了一个SpringApplication对象,注入了入口函数的Class(作用:获取@EnableAutoConfiguration注解)和args,并调用了SpringApplication对象的run()方法
2、构造初始化
public SpringApplication(Object... sources) { initialize(sources); } @SuppressWarnings({ "unchecked", "rawtypes" }) private void initialize(Object[] sources) { if (sources != null && sources.length > 0) { this.sources.addAll(Arrays.asList(sources)); } this.webEnvironment = deduceWebEnvironment(); //推测当前是否是web环境 setInitializers((Collection) getSpringFactoriesInstances( ApplicationContextInitializer.class)); setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass = deduceMainApplicationClass(); }
这里的mainApplicationClass就是我们自己写的MainInit类
3、SpringApplication.run()
public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; FailureAnalyzers analyzers = null; configureHeadlessProperty(); SpringApplicationRunListeners listeners = getRunListeners(args); listeners.started(); try { ApplicationArguments applicationArguments = new DefaultApplicationArguments( args); ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); Banner printedBanner = printBanner(environment); context = createApplicationContext(); analyzers = new FailureAnalyzers(context); prepareContext(context, environment, listeners, applicationArguments, printedBanner); refreshContext(context); afterRefresh(context, applicationArguments); listeners.finished(context, null); stopWatch.stop(); if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass) .logStarted(getApplicationLog(), stopWatch); } return context; } catch (Throwable ex) { handleRunFailure(context, listeners, analyzers, ex); throw new IllegalStateException(ex); } }
看到这里,如果追过spring源码的老司机应该就很熟悉,这里初始化了spring,afterRefresh(context, applicationArguments)最终会调用AbstractApplicationContext.refresh()方法中,在这里会构建spring的ioc容器
4、构建ioc容器
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
这里构建了IOC容器,因为在pom.xml中我们加入了spring mvc的依赖,这里spring boot会自动把spring mvc所需要的bean注册到IOC容器中,这里我们不看IOC容器是如果构建的,只关心spring boot 是如何自动把spring mvc所需要的bean注册到IOC容器中的。还记得@EnableAutoConfiguration注解吗?(如果忘了,请翻到博客头部回忆一下)下面是EnableAutoConfiguration注解的源码
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(EnableAutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; /** * Exclude specific auto-configuration classes such that they will never be applied. * @return the classes to exclude */ Class<?>[] exclude() default {}; /** * Exclude specific auto-configuration class names such that they will never be * applied. * @return the class names to exclude * @since 1.3.0 */ String[] excludeName() default {}; }
主要看EnableAutoConfigurationImportSelector这个类,这个类会导入spring boot中的一个配置文件,方法如下:
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = SpringFactoriesLoader.loadFactoryNames( getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you " + "are using a custom packaging, make sure that file is correct."); return configurations; }
这个方法会导入spring-boot-autoconfigure包下META-INF/spring.factories配置文件
spring.factories
# Initializers org.springframework.context.ApplicationContextInitializer=\ org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\ org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer # Application Listeners org.springframework.context.ApplicationListener=\ org.springframework.boot.autoconfigure.BackgroundPreinitializer # 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.MessageSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration,\ 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.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.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.jms.hornetq.HornetQAutoConfiguration,\ 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.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.velocity.VelocityAutoConfiguration,\ org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\ org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\ org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\ 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 # Failure analyzers org.springframework.boot.diagnostics.FailureAnalyzer=\ org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,\ org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer,\ org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer # Template availability providers org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\ org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,\ org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider,\ org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,\ org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,\ org.springframework.boot.autoconfigure.velocity.VelocityTemplateAvailabilityProvider,\ org.springframework.boot.autoconfigure.web.JspTemplateAvailabilityProvider
通过getCandidateConfigurations方法,会把配置文件中org.springframework.boot.autoconfigure.EnableAutoConfiguration=后的所有配置类的全类名信息读取到一个List集合中,这里看到一个比较亲切的名字org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration看类名就能猜到这应该就是我们需要找东西了。2016年12月21日23:43:06 时间不早,(~﹃~)~zZ 下次再战,预知后事如何,请听下回分解
相关文章推荐
- Spring Boot起步依赖源码分析(二)
- spring boot实战(第十四篇)整合RabbitMQ源码分析前言
- Spring依赖注入源码分析
- (转)spring boot实战(第三篇)事件监听源码分析
- Spring Boot启动过程源码分析
- spring源码分析 循环依赖
- [Spring Boot] 1. Spring Boot启动过程源码分析
- spring依赖注入源码分析和mongodb自带连接本地mongodb服务逻辑分析
- 深入研究Spring-IoC:源码分析依赖注入
- Spring boot源码分析-环境搭建
- spring-boot源码分析(1)--从main方法开始
- spring boot源码分析之SpringApplication
- Spring源码分析----IOC依赖注入
- SpringBoot-Loader源码分析系列2:启动 new JarLauncher().launch(args)的.launch(args)部分
- SpringBoot起步依赖和自动配置
- spring boot实战(第六篇)加载application资源文件源码分析
- Spring Boot 源码分析
- Spring -- 依赖注入源码分析
- Spring -- 依赖注入源码分析(二)
- Spring Boot - security 实战与源码分析