转载

SpringBoot 注解@EnableAutoConfiguration

之前使用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

原文  http://www.huxd.org/articles/2017/08/15/1502809082404.html
正文到此结束
Loading...