How do we look at the source code SpringBoot

1, quickly generate a simple project SpringBoot

Enter the address: start.spring.io/ , click generate code.

2. Notes: @SpringBootApplication

A Web project, only this line comments. There are so bad? We take a look at what it actually done?

@SpringBootApplication
public class SpringBootDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootDemoApplication.class, args);
    }

}复制代码

The @SpringBootApplication annotation is equivalent to using @Configuration , @EnableAutoConfiguration , and @ComponentScan with their default attributes

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
        @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {复制代码

Look at the code, obviously @SpringBootConfigurationthen, is how to say @Configurationit?

2.1 Notes: @SpringBootConfiguration

@Configuration
public @interface SpringBootConfiguration {  
}复制代码

Before moving on to go inside, they discovered a Componentcomment? It is not very familiar with it?

@Component
public @interface Configuration {复制代码

Spring provides further stereotype annotations: @Component , @Service , and @Controller . @Component is a generic stereotype for any Spring-managed component. @Repository , @Service, and @Controller are specializations of @Component for more specific use cases (in the persistence, service, and presentation layers, respectively)。

2.2 Notes: @ComponentScan

org.springframework.boot.SpringApplication  
// 第1步
public ConfigurableApplicationContext run(String... args) {  
    refreshContext(context);
}
// 第2步
public ConfigurableApplicationContext run(String... args) {  
    ConfigurableApplicationContext context = null;
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
    configureHeadlessProperty();
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting();
    try {
        ConfigurableEnvironment environment = prepareEnvironment(listeners,
                applicationArguments);
        configureIgnoreBeanInfo(environment);
        Banner printedBanner = printBanner(environment);
        context = createApplicationContext();
        exceptionReporters = getSpringFactoriesInstances(
                SpringBootExceptionReporter.class,
                new Class[] { ConfigurableApplicationContext.class }, context);
        prepareContext(context, environment, listeners, applicationArguments,
                printedBanner);
        refreshContext(context);
        afterRefresh(context, applicationArguments);
        listeners.started(context);
        // Called after the context has been refreshed.
        callRunners(context, applicationArguments);
    }
    listeners.running(context);

    return context;
}
// 第3步
protected void refresh(ApplicationContext applicationContext) {  
        Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
        ((AbstractApplicationContext) applicationContext).refresh();
}
// 第4步
org.springframework.context.support.AbstractApplicationContext  
public void refresh() throws BeansException, IllegalStateException {  
    // Invoke factory processors registered as beans in the context.
    invokeBeanFactoryPostProcessors(beanFactory);
}
// 第5步
org.springframework.context.support.PostProcessorRegistrationDelegate  
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {  
    if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
        registryProcessor.postProcessBeanDefinitionRegistry(registry);
    }
}
// 第6步
org.springframework.context.annotation.ConfigurationClassPostProcessor  
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {  
    processConfigBeanDefinitions(registry);
}
// 第7步
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {  
    do {
        parser.parse(candidates);
    }
}
// 第8步
org.springframework.context.annotation.ConfigurationClassParser  
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {  
    do {
        sourceClass = doProcessConfigurationClass(configClass, sourceClass);
    }
}
// 第9步
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)  
        throws IOException {
    // Process any @PropertySource annotations
    for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
            sourceClass.getMetadata(), PropertySources.class,
            org.springframework.context.annotation.PropertySource.class)) {
        if (this.environment instanceof ConfigurableEnvironment) {
            processPropertySource(propertySource);
        }
        else {
            logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
                    "]. Reason: Environment must implement ConfigurableEnvironment");
        }
    }
    // Process any @ComponentScan annotations
    Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
            sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
    if (!componentScans.isEmpty() &&
            !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
        for (AnnotationAttributes componentScan : componentScans) {
            // The config class is annotated with @ComponentScan -> perform the scan immediately
            Set<BeanDefinitionHolder> scannedBeanDefinitions =
                    this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
            // Check the set of scanned definitions for any further config classes and parse recursively if needed
            for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
                BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
                if (bdCand == null) {
                    bdCand = holder.getBeanDefinition();
                }
                if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
                    parse(bdCand.getBeanClassName(), holder.getBeanName());
                }
            }
        }
    }
    // Process any @Import annotations
    processImports(configClass, sourceClass, getImports(sourceClass), true);
    // Process any @ImportResource annotations
    AnnotationAttributes importResource =
            AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
    if (importResource != null) {
        String[] resources = importResource.getStringArray("locations");
        Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
        for (String resource : resources) {
            String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
            configClass.addImportedResource(resolvedResource, readerClass);
        }
    }
}
// 第10步
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,  
        Collection<SourceClass> importCandidates, boolean checkForCircularImports) {
    String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
    Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
    processImports(configClass, currentSourceClass, importSourceClasses, false);
}

// 第11步
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector  
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {  
    AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
            autoConfigurationMetadata, annotationMetadata);
}
// 第12步
private List<String> filter(List<String> configurations,  
        AutoConfigurationMetadata autoConfigurationMetadata) {
    for (AutoConfigurationImportFilter filter : getAutoConfigurationImportFilters()) {
        invokeAwareMethods(filter);
        boolean[] match = filter.match(candidates, autoConfigurationMetadata);
        for (int i = 0; i < match.length; i++) {
            if (!match[i]) {
                skip[i] = true;
                candidates[i] = null;
                skipped = true;
            }
        }
    }
    return new ArrayList<>(result);
}
// 第13步
protected List<AutoConfigurationImportFilter> getAutoConfigurationImportFilters() {  
    return SpringFactoriesLoader.loadFactories(AutoConfigurationImportFilter.class,
        this.beanClassLoader);
}
// 第14步
org.springframework.core.io.support.SpringFactoriesLoader  
public static <T> List<T> loadFactories(Class<T> factoryClass, @Nullable ClassLoader classLoader) {  
    List<String> factoryNames = loadFactoryNames(factoryClass, classLoaderToUse);
    return result;
}
// 第15步
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {  
    try {
        Enumeration<URL> urls = (classLoader != null ?
                classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
                ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
        return result;
    }
}
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";复制代码

That, in fact, spring.factoriesis spring-corefunctional.

Look at the spring-boot-autoconfigureitems inside spring.factories.

# Initializers
org.springframework.context.ApplicationContextInitializer=\  
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\  
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener

# Application Listeners
org.springframework.context.ApplicationListener=\  
org.springframework.boot.autoconfigure.BackgroundPreinitializer

# Auto Configuration Import Listeners
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\  
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener

# Auto Configuration Import Filters
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\  
org.springframework.boot.autoconfigure.condition.OnBeanCondition,\  
org.springframework.boot.autoconfigure.condition.OnClassCondition,\  
org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition

# 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.CloudServiceConnectorsAutoConfiguration,\  
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.CassandraReactiveDataAutoConfiguration,\  
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\  
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\  
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\  
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\  
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\  
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.jdbc.JdbcRepositoriesAutoConfiguration,\  
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\  
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\  
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\  
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\  
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\  
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.RedisReactiveAutoConfiguration,\  
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.elasticsearch.rest.RestClientAutoConfiguration,\  
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\  
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.http.HttpMessageConvertersAutoConfiguration,\  
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\  
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\  
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.groovy.template.GroovyTemplateAutoConfiguration,\  
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\  
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\  
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\  
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.mongo.embedded.EmbeddedMongoAutoConfiguration,\  
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\  
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\  
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\  
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\  
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\  
org.springframework.boot.autoconfigure.reactor.core.ReactorCoreAutoConfiguration,\  
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\  
org.springframework.boot.autoconfigure.security.servlet.SecurityRequestMatcherProviderAutoConfiguration,\  
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\  
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\  
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\  
org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\  
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\  
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\  
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\  
org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\  
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\  
org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\  
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\  
org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,\  
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,\  
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.client.RestTemplateAutoConfiguration,\  
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\  
org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\  
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\  
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\  
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\  
org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration,\  
org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\  
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\  
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\  
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\  
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\  
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\  
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\  
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\  
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\  
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\  
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,\  
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration

# 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,\  
org.springframework.boot.autoconfigure.session.NonUniqueSessionRepositoryFailureAnalyzer

# 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.web.servlet.JspTemplateAvailabilityProvider复制代码

See here, is not it a little doubts, why we did not do anything, it already has so many features. Because when the project started, we have built so much give service.

3, where the vessel started?

Why Tomcat 3.1 is the default startup?

We go back to the beginning, why start time to see the Tomcatlog it?

Connected to the target VM, address: '127.0.0.1:56945', transport: 'socket'

  .                 _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |    | .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                        

2019-06-13 09:15:11.818  INFO 16978 --- [           main] c.e.s.SpringBootDemoApplication          : Starting SpringBootDemoApplication on bogon with PID 16978 (/Users/chenyuan/Dropbox/Workspaces/IdeaProjects/spring-boot-demo/target/classes started by chenyuan in /Users/chenyuan/Dropbox/Workspaces/IdeaProjects/spring-src-leaning)  
2019-06-13 09:15:11.823  INFO 16978 --- [           main] c.e.s.SpringBootDemoApplication          : No active profile set, falling back to default profiles: default

// 这里日志显示,有一个embedded的tomcat启动了8080端口
2019-06-13 09:15:13.597  INFO 16978 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)  
2019-06-13 09:15:13.644  INFO 16978 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]  
2019-06-13 09:15:13.645  INFO 16978 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.14]  
2019-06-13 09:15:13.653  INFO 16978 --- [           main] o.a.catalina.core.AprLifecycleListener   : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/Users/chenyuan/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.]  
2019-06-13 09:15:13.752  INFO 16978 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext  
2019-06-13 09:15:13.752  INFO 16978 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1862 ms  
2019-06-13 09:15:14.018  INFO 16978 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'  
2019-06-13 09:15:14.226  INFO 16978 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''  
2019-06-13 09:15:14.231  INFO 16978 --- [           main] c.e.s.SpringBootDemoApplication          : Started SpringBootDemoApplication in 3.007 seconds (JVM running for 3.924)复制代码
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\复制代码
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration  
@Bean
    @ConditionalOnClass(name = "org.apache.catalina.startup.Tomcat")
    public TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer(
            ServerProperties serverProperties) {
        return new TomcatServletWebServerFactoryCustomizer(serverProperties);
    }复制代码

<!-- spring-boot-demo/pom.xml -->  
<dependency>  
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- spring-boot-starter-web/pom.xml -->  
<dependency>  
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>

<!-- spring-boot-starters/spring-boot-starter-tomcat/pom.xml -->  
<dependency>  
  <groupId>org.apache.tomcat.embed</groupId>
  <artifactId>tomcat-embed-core</artifactId>
  <exclusions>
    <exclusion>
      <groupId>org.apache.tomcat</groupId>
      <artifactId>tomcat-annotations-api</artifactId>
    </exclusion>
  </exclusions>
</dependency>复制代码

3.2 If you want to specify a different container it?

<dependencies>  
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jetty</artifactId>
    </dependency>
</dependencies>复制代码

The project Tomca the starter commented, Jetty container can be introduced.

After such a replacement, but also why it was introduced?

org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration  
@Configuration
@ConditionalOnClass({ Servlet.class, Server.class, Loader.class,WebAppContext.class })
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
public static class EmbeddedJetty {  
  @Bean
  public JettyServletWebServerFactory JettyServletWebServerFactory() {
    return new JettyServletWebServerFactory();
  }
}复制代码

The @ConditionalOnClass and @ConditionalOnMissingClass annotations let @Configurationclasses be included based on the presence or absence of specific classes.

Here Servlet.class, Server.class, Loader.class,WebAppContext.classis the Jetty inside the package.

Here also we designed a factory pattern to obtain a WebServer.

@FunctionalInterface
public interface ServletWebServerFactory {

    /**
     * Gets a new fully configured but paused {@link WebServer} instance. Clients should
     * not be able to connect to the returned server until {@link WebServer#start()} is
     * called (which happens when the {@link ApplicationContext} has been fully
     * refreshed).
     * @param initializers {@link ServletContextInitializer}s that should be applied as
     * the server starts
     * @return a fully configured and started {@link WebServer}
     * @see WebServer#stop()
     */
    WebServer getWebServer(ServletContextInitializer... initializers);

}复制代码

3.3 That is when the initialization container it?

// 第1步
org.springframework.context.support.AbstractApplicationContext  
public void refresh() throws BeansException, IllegalStateException {  
  synchronized (this.startupShutdownMonitor) {
    try {
      // Initialize other special beans in specific context subclasses.
      onRefresh();
    }
}
// 第2步
org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext  
protected void onRefresh() {  
    super.onRefresh();
    try {
        createWebServer();
    }
    catch (Throwable ex) {
        throw new ApplicationContextException("Unable to start web server", ex);
    }
}
// 第3步
private void createWebServer() {  
    WebServer webServer = this.webServer;
    ServletContext servletContext = getServletContext();
    if (webServer == null && servletContext == null) {
        ServletWebServerFactory factory = getWebServerFactory();
        this.webServer = factory.getWebServer(getSelfInitializer());
    }
    else if (servletContext != null) {
        try {
            getSelfInitializer().onStartup(servletContext);
        }
        catch (ServletException ex) {
            throw new ApplicationContextException("Cannot initialize servlet context",
                    ex);
        }
    }
    initPropertySources();
}复制代码

After seeing factory.getWebServer, it is not on all the series up?

Thanks for reading to the end of the text, eggs offer

java core notes, BAT face questions, architecture advanced video, e-books

Some of the information below:



Reproduced in: https: //juejin.im/post/5d034c1f6fb9a07ef7107040

Guess you like

Origin blog.csdn.net/weixin_34279061/article/details/93177090
Recommended