目錄html
@SpringBootApplication public class LearnspringbootApplication { public static void main(String[] args) { SpringApplication.run(LearnspringbootApplication.class, args); } }
你們能夠看到,如上所示是一個很常見的SpringBoot啓動類,咱們能夠看到僅僅使用了一個Main方法就啓動了整個SpringBoot項目是否是很神奇,下面咱們來仔細剖析如下這一段代碼,這段代碼中咱們能夠仔細地觀察到最重要的兩個部分,分別是@SpringBootApplication
註解和SpringApplication
這個類。java
打開這個@SpringBootApplication
註解,以下所示react
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) public @interface SpringBootApplication { @AliasFor(annotation = EnableAutoConfiguration.class) Class<?>[] exclude() default {}; @AliasFor(annotation = EnableAutoConfiguration.class) String[] excludeName() default {}; @AliasFor(annotation = ComponentScan.class, attribute = "basePackages") String[] scanBasePackages() default {}; @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses") Class<?>[] scanBasePackageClasses() default {}; }
咱們能夠發現;咱們能夠在@SpringBootApplication
註解中使用exclude()
,excludeName()
,scanBasePackages()
,scanBasePackageClasses()
這四個方法來進行自定義咱們須要排除裝配的Bean,掃描包路徑,掃描類路徑。web
搭眼一瞅,在@SpringBootApplication
註解上還有下面那麼多註解。redis
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
這四個註解不用看,就是關於註解的一些定義spring
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited
@SpringBootConfiguration
註解咱們點進去看一下,發現是下面這個樣子,@SpringBootConfiguration註解上又標註了@Configuration註解,想必在@Configuration註解上也標註了@Component註解,這不就是咱們上一章節說的Spring的模式註解。總的來講嘛,SpringBootConfiguration註解的做用就是把類變成能夠被Spring管理的Beanjson
結論 1 :也就是說標註
@SpringBootApplication
註解的類會成爲Spring的Beanspringboot
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration public @interface SpringBootConfiguration { }
咱們再來看一下@EnableAutoConfiguration
,從名字上咱們就能夠看到「啓用自動裝配」
的意思。那咱們可要仔細看一下。從下面咱們能夠看到只有兩個咱們須要瞭解的註解,分別是@AutoConfigurationPackage
和@Import
註解。websocket
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(AutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class<?>[] exclude() default {}; String[] excludeName() default {}; }
當我點進去@AutoConfigurationPackage
註解中,發現該註解又啓用了一個模塊裝配@Import(AutoConfigurationPackages.Registrar.class)
(上一章節有講到);因此又點進去AutoConfigurationPackages.Registrar.class
這個類,發現這個類又實現了兩個接口ImportBeanDefinitionRegistrar
和DeterminableImports
在該類的實現方法中的PackageImport()
;最後終於發現了下面這段代碼。session
PackageImport(AnnotationMetadata metadata) { this.packageName = ClassUtils.getPackageName(metadata.getClassName()); }
結論 2 :SpringBoot默認會裝配啓動類路徑的全部包下可裝配的Bean;也就是說若是你把SpringBoot啓動類放在一個單獨的包中,則SpringBoot不會裝配到你的其餘Bean。這時候你就要使用
@SpringBootApplication
的scanBasePackages()
方法進行另行配置。
此時@EnableAutoConfiguration
註解僅僅就剩下@Import(AutoConfigurationImportSelector.class)
沒有看了,不過從註解上咱們能夠看到使用@Import
註解,因此能夠知道SpringBoot使用的是模塊裝配的接口實現方式
。因此我麼針對AutoConfigurationImportSelector
這個類仔細剖析一下。AutoConfigurationImportSelector
- > AutoConfigurationImportSelector.selectImports()
->getAutoConfigurationEntry()
-> getCandidateConfigurations()
->SpringFactoriesLoader.loadFactoryNames()
-> loadFactoryNames()
->loadSpringFactories()
; 哈哈果真源碼不經扒;看下面源碼;META-INF/spring.factories
這不就是配置SpringBoot自動配置的文件嘛。
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories"; Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) : ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
結論 3 :SpringBoot在啓動時會自動加載Classpth路徑下的
META-INF/spring.factories
文件,因此咱們能夠將須要自動配置的Bean寫入這個文件,SPringBoot會替咱們自動裝配。這也正是配置SpringBoot自動配置的步驟。
@SpringBootApplication public class LearnspringbootApplication { public static void main(String[] args) { SpringApplication.run(LearnspringbootApplication.class, args); } }
在Main方法中咱們能夠看到SpringApplication做爲一個啓動類來啓動SpringBoot應用程序。那麼SpringApplication類是如何進行啓動整個應用程序的呢?
public SpringApplication(Class<?>... primarySources) { this(null, primarySources); }
從SpringApplication類的構造方法中咱們能夠看到,這裏傳入了一個主Bean來源;由於咱們將標註了@SpringBootApplication
註解的LearnspringbootApplication.class
傳遞了進來,因此@SpringBootApplication
掃描到的Bean和自動裝配的Bean會做爲主Bean來源。固然咱們能夠調用該類的setSources()
方法設置本身的SpringXML配置。
this.webApplicationType = WebApplicationType.deduceFromClasspath();
從上面一句代碼(既SpringApplication初始化方法中一行代碼);咱們觀察deduceFromClasspath()
方法能夠看到,SpringBoot判斷類路徑下是否存在下面類進而判斷SpringBoot的應用類型。三種類型分別是NONE
,SERVLET
,REACTIVE
。固然咱們也能夠調用setWebApplicationType()
自行設置。
private static final String[] SERVLET_INDICATOR_CLASSES = { "javax.servlet.Servlet", "org.springframework.web.context.ConfigurableWebApplicationContext" }; private static final String WEBMVC_INDICATOR_CLASS = "org.springframework." + "web.servlet.DispatcherServlet"; private static final String WEBFLUX_INDICATOR_CLASS = "org." + "springframework.web.reactive.DispatcherHandler"; private static final String JERSEY_INDICATOR_CLASS = "org.glassfish.jersey.servlet.ServletContainer"; private static final String SERVLET_APPLICATION_CONTEXT_CLASS = "org.springframework.web.context.WebApplicationContext"; private static final String REACTIVE_APPLICATION_CONTEXT_CLASS = "org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext";
this.mainApplicationClass = deduceMainApplicationClass();
從上面一句代碼(既SpringApplication初始化方法中一行代碼);咱們能夠經過deduceMainApplicationClass()
方法能夠看到SpringBoot根據Main 線程執行堆棧判斷實際的引導類。(PS:存在一種狀況就是標註@SpringBootApplication
註解的並非引導類狀況)
private Class<?> deduceMainApplicationClass() { try { StackTraceElement[] stackTrace = new RuntimeException().getStackTrace(); for (StackTraceElement stackTraceElement : stackTrace) { if ("main".equals(stackTraceElement.getMethodName())) { return Class.forName(stackTraceElement.getClassName()); } } } catch (ClassNotFoundException ex) { // Swallow and continue } return null; }
setInitializers((Collection) getSpringFactoriesInstances( ApplicationContextInitializer.class));
從上面一句代碼(既SpringApplication初始化方法中一行代碼);咱們發現setInitializers()
方法會調用getSpringFactoriesInstances()
-> getSpringFactoriesInstances()
-> getSpringFactoriesInstances()
該方法會使用SpringFactoriesLoader
類記進行加載配置資源既META-INF/spring.factories
,利用 Spring 工廠加載機制,實例化 ApplicationContextInitializer 實現類,並排序對象集合。並使用AnnotationAwareOrderComparator
類的sort()
方法進行排序。
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) { ClassLoader classLoader = getClassLoader(); // Use names and ensure unique to protect against duplicates Set<String> names = new LinkedHashSet<>( SpringFactoriesLoader.loadFactoryNames(type, classLoader)); List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names); AnnotationAwareOrderComparator.sort(instances); return instances; }
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
從上面一句代碼(既SpringApplication初始化方法中一行代碼);從setListeners()
方法中能夠看到該方法仍然調用getSpringFactoriesInstances()
方法,不一樣的是利用 Spring 工廠加載META-INF/spring.factories
,實例化 ApplicationListener
實現類,並排序對象集合
從SpringApplication
類的run()
方法中,咱們能夠看到下面代碼getRunListeners()
方法一樣利用 Spring 工廠加載機制,讀取 SpringApplicationRunListener 對象集合,而且封裝到組合類
SpringApplicationRunListeners對象中並啓動運行監聽器。
SpringApplicationRunListeners listeners = getRunListeners(args); listeners.starting();
Spring Boot 經過 SpringApplicationRunListener 的實現類 EventPublishingRunListener 利用 Spring Framework 事件
API ,廣播 Spring Boot 事件。
context = createApplicationContext();
從SpringApplication
類的run()
方法中,咱們可看到createApplicationContext()
根據第二步推斷的SpringBoot應用類型建立相應的上下文。
protected ConfigurableApplicationContext createApplicationContext() { Class<?> contextClass = this.applicationContextClass; if (contextClass == null) { try { switch (this.webApplicationType) { case SERVLET: contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS); break; case REACTIVE: contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS); break; default: contextClass = Class.forName(DEFAULT_CONTEXT_CLASS); } } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Unable create a default ApplicationContext, " + "please specify an ApplicationContextClass", ex); } } return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass); }
根據推斷的SpringBoot應用類型建立下面三種之一的上下文
public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context." + "annotation.AnnotationConfigApplicationContext"; public static final String DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot." + "web.servlet.context.AnnotationConfigServletWebServerApplicationContext"; public static final String DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework." + "boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext";
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); configureIgnoreBeanInfo(environment);
從SpringApplication
類的run()
方法中,咱們可看到prepareEnvironment()
根據第二步推斷的SpringBoot應用類型建立相應的上下文。建立不一樣的Environment
。從下面能夠看到他們分別是StandardServletEnvironment
,StandardReactiveWebEnvironment
,StandardEnvironment
private ConfigurableEnvironment getOrCreateEnvironment() { if (this.environment != null) { return this.environment; } switch (this.webApplicationType) { case SERVLET: return new StandardServletEnvironment(); case REACTIVE: return new StandardReactiveWebEnvironment(); default: return new StandardEnvironment(); } }
標註@SpringBootApplication
註解的類會成爲Spring的Bean
SpringBoot默認會裝配啓動類路徑的全部包下可裝配的Bean;也就是說若是你把SpringBoot啓動類放在一個單獨的包中,則SpringBoot不會裝配到你的其餘Bean。這時候你就要使用@SpringBootApplication
的scanBasePackages()
方法進行另行配置。
SpringBoot在啓動時會自動加載Classpth路徑下的META-INF/spring.factories
文件,因此咱們能夠將須要自動配置的Bean寫入這個文件。一樣SpringBoot也會掃描Jar包中的META-INF/spring.factories
文件;例如當導入spring-boot-starter
起步依賴的時候,而且啓用了自動裝配註解@EnableAutoConfiguration
,就將會替咱們自動裝配如以下類;若是知足條件的話。
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
該教程所屬Java工程師之SpringBoot系列教程,本系列相關博文目錄 Java工程師之SpringBoot系列教程前言&目錄