之前使用SpringBoot是没有什么问题的,今天整合一下,突然发现报错
org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean. at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:137) ~[spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537) ~[spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] at com.example.demo.DemoApplication.main(DemoApplication.java:9) [classes/:na] Caused by: org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean. at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:189) ~[spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:162) ~[spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:134) ~[spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE] ... 8 common frames omitted Process finished with exit code 1
瞬间懵逼。
后来经过排查发现无法启动嵌入容器,工厂类不存在。后来在类头加上 @EnableAutoConfiguration。就OK了。
下一步,查看一下这个 @EnableAutoConfiguration究竟是干什么的。
通过观察源码发现这个注解引入了其他的注解
package org.springframework.boot.autoconfigure; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.context.annotation.Import; @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import({EnableAutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class[] exclude() default {}; String[] excludeName() default {}; }
主要查看的是
@Import({EnableAutoConfigurationImportSelector.class})
import主要配合Configuration使用,用来导出更多的Configuration类,同时,enableautoconfigurationimportselector实现了DeferredImportSelector接口,并实现了selectImports方法
public interface ImportSelector { String[] selectImports(AnnotationMetadata var1);
}
导出的类是通过SpringFactoriesLoader.loadFactoryNames()读取了ClassPath下面的META-INF/spring.factories文件
# Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=/ 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.cloud.CloudAutoConfiguration,/ org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,/ org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,/ org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,/ org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,/ org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,/ org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,/ org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,/ org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,/ org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,/ org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,/ org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,/ org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,/ org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,/ 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.hornetq.HornetQAutoConfiguration,/ org.springframework.boot.autoconfigure.jta.JtaAutoConfiguration,/ org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchAutoConfiguration,/ org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchDataAutoConfiguration,/ org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,/ org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,/ org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,/ org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,/ org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,/ org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,/ org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoConfiguration,/ org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,/ org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,/ org.springframework.boot.autoconfigure.mongo.MongoDataAutoConfiguration,/ org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,/ org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,/ org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration,/ org.springframework.boot.autoconfigure.redis.RedisAutoConfiguration,/ org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,/ org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,/ 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.web.DispatcherServletAutoConfiguration,/ org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,/ org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration,/ org.springframework.boot.autoconfigure.web.GzipFilterAutoConfiguration,/ 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.WebMvcAutoConfiguration,/ org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration
其中EmbeddedServletContainerAutoConfiguration是实现web服务的主要配置文类,这个类会根据当前存在的类的信息注入必要的EmbeddedServletContainerFactory类。
spring-boot-starter-tomcat引入了tomcat的依赖,所以EmbeddedServletContainerAutoConfiguration发现存在Tomcat.class就会注入TomcatEmbeddedServletContainerFactory来内置web容器。
@Configuration @ConditionalOnClass({ Servlet.class, Tomcat.class }) @ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT) public static class EmbeddedTomcat { @Bean public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() { return new TomcatEmbeddedServletContainerFactory(); } }
主要参考:http://www.jianshu.com/p/2a171fa80756