《02.Spring Boot連載:Spring Boot實戰.Spring Boot核心原理剖析》

在上節中我們通過了一個小的入門案例已經看到了Spring Boot的強大和簡單之處。本章將詳細介紹Spring Boot的核心註解,基本配置和運行機制。筆者一直認爲:精通一個技術一定要深入瞭解這個技術幫助我們做了哪些動作,深入理解它底層的運行原理,只有達到這個目標纔可以熟練使用框架,最終達到融會貫通的目的。

一.啓動類與@SpringBootApplication

Spring Boot的項目一般都會有註解*Application標註的入口類,入口類中會有一個main方法,main方法是一個標準的Java應用程序的入口方法,可以直接啓動。 @SpringBootApplication註解是Spring Boot的核心註解,用此註解標註的入口類是應用的啓動類,通常會在啓動類的main方法中通過 SpringApplication.run(App.class, args) 來啓動Spring Boot應用項目。 @SpringBootApplication其實是一個組合註解,查看源碼如下:

  1. // 程序清單:org/springframework/boot/autoconfigure/SpringBootApplication
    @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, attribute = "exclude")
        Class<?>[] exclude() default {};
        @AliasFor(annotation = EnableAutoConfiguration.class, attribute = "excludeName")
        String[] excludeName() default {};
        @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
        String[] scanBasePackages() default {};
        @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
        Class<?>[] scanBasePackageClasses() default {};
    }

 (1)@SpringBootConfiguration:這是Spring Boot項目的配置註解,這也是一個組合註解: 

  1. //程序清單:org/springframewor/boot/SpringBootConfiguration
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Configuration
    public @interface SpringBootConfiguration {

 (2)@EnableAutoConfiguration:啓動自動配置,該註解會讓Spring Boot根據當前項目所依賴的jar包自動配置項目的相關配置項。 例如,當我們在Spring Boot項目的pom.xml文件中配置了spring-boot-starter-web依賴:

  1. <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

2.1spring-boot-starter-web自動配置.png

                                圖2.1 spring-boot-starter-web自動配置圖

通過上述例子可以看出,如果我們又在項目中添加spring-boot-starter-data-solr依賴,Spring Boot就會自動進行Solr技術的相關配置。 (3) @ComponentScan:掃描配置,Spring Boot默認會掃描@SpringBootApplication所在類的同級包以及它的子包。所以建議將@SpringBootApplication修飾的入口類放置在項目包下(Group Id+Artifact Id),這樣做的好處是:可以保證Spring Boot項目自動掃描到項目所有的包。


二.Spring Boot基本配置介紹

1 關閉某個自動配置

通過上節@SpringBootApplication下的@EnableAutoConfiguration得知,Spring Boot會根據項目中的jar包依賴,自動做出配置,Spring Boot支持的自動配置如下(非常多):

2.2 Spring Boot的自動配置.png

假如我們不需要Spring Boot自動配置,想關閉某一項的自動配置,該如何設置呢? 例如:我們不想自動配置Redis,想自己手動配置呢?通過查看@SpringBootApplication的源碼可以看出,關閉特定的自動配置應該使用@SpringBootApplication下的exclude參數,現以關閉Redis自動配置爲例: @SpringBootApplication(exclude={RedisAutoConfiguration.class})

2.定製啓動Banner

在啓動Spring Boot項目的時候我們在控制檯下看到了如下默認的啓動圖案:


 如果想自己來指定啓動的圖案應該如何配置呢?

 (1) 在瀏覽器中打開網站http://patorjk.com/software/taag,如下圖:

2.3 啓動圖案.png

(2)在第一步所示範的網站上選擇左下方的“select & copy”按鈕將自定義的banner圖案進行復制,然後新建一個banner.txt文件,將複製好的圖案寫入到banner.txt文件中。

2.4 自定義banner.png

(3)將banner.txt文件放置到項目的src/main/resources目錄下。

2.5 banner.txt文件的位置.png

(4)重新啓動程序,查看效果如下:

2.6 banner啓動效果圖.png

3. 應用的全局配置文件

可以在Spring Boot項目的src/main/resources目錄下或者在類路徑下的/config目錄下創建一個全局的配置文件application.properties或者是後綴爲.yml的application.yml的文件用於修改Spring Boot項目的默認配置值,例如修改項目的默認端口,或者進入DispatcherServlet的請求地址規則等。 通常,在實際開發中我們習慣使用application.properties文件作爲應用的全局配置文件,一般我們放到src/main/resources目錄下。 例如,在src/main/resources目錄下創建一個名稱爲application.properties的文件,配置內容如下:

server.port=9999
server.servlet-path=*.action

(1)其中, server.port參數用於將Spring Boot項目的默認端口改爲9999,啓動應用,端口修改後如下圖所示:

2.7 修改項目端口.png

 (2) server.servlet-path參數用於將進入DispatcherServlet的規則修改爲:*.action,測試如下:

2.8 訪問項目.png

 從上面的參數配置可以看出,Spring Boot支持很多參數的配置與參數值的修改,關於其他配置參數的詳細說明和描述可以查看官方的文檔說明:http://docs.spring.io/spring-boot/docs/1.5.6.RELEASE/reference/htmlsingle/#common-application-properties

4 Starters啓動器

Spring Boot爲我們提供了簡化項目開發的Starter啓動器,例如我們在項目中使用的pom.xml文件下配置:

  1. <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

Spring Boot就會自動關聯web開發相關的依賴,如Tomcat以及spring-webmvc等,進而對web開發進行支持,同時相關技術的配置也將實現自動配置,程序員即可從繁瑣的配置文件中脫身而出了。除此之外,官方還提供瞭如下Starters:

  1. spring-boot-starter:這是Spring Boot的核心啓動器,包含了自動配置、日誌和YAML文件的支持。
    spring-boot-starter-activemq:爲JMS使用Apache ActiveMQ    ActiveMQ 是Apache出品,最流行的,能力強勁的開源消息總線
    spring-boot-starter-amqp:通過spring-rabbit來支持AMQP協議(Advanced Message Queuing Protocol)。
    spring-boot-starter-aop:支持面向方面的編程即AOP,包括spring-aop和AspectJ。
    spring-boot-starter-artemis:通過Apache Artemis支持JMS的API(Java Message Service API)。
    spring-boot-starter-batch:支持Spring Batch,包括HSQLDB數據庫。
    spring-boot-starter-cache:支持Spring的Cache抽象。
    spring-boot-starter-cloud-connectors:支持Spring Cloud Connectors,簡化了在像Cloud Foundry或Heroku這樣的雲平臺上連接服務。
    spring-boot-starter-data-cassandra:使用Cassandra分佈式數據庫、Spring Data Cassandra,Apache Cassandra是一套開源分佈式NoSQL數據庫系統。
    spring-boot-starter-data-couchbase:使用Couchbase 文件存儲數據庫、Spring Data Couchbase。Spring Data是一個用於簡化數據庫訪問,並支持雲服務的開源框架。
    spring-boot-starter-data-elasticsearch:支持ElasticSearch搜索和分析引擎,包括spring-data-elasticsearch。
    spring-boot-starter-data-gemfire:支持GemFire分佈式數據存儲,包括spring-data-gemfire。
    spring-boot-starter-data-jpa:支持JPA(Java Persistence API),包括spring-data-jpa、spring-orm、Hibernate。
    spring-boot-starter-data-ldap:支持 Spring Data LDAP。
    spring-boot-starter-data-mongodb:支持MongoDB數據,包括spring-data-mongodb。
    spring-boot-starter-data-neo4j:使用Neo4j圖形數據庫、Spring Data Neo4j    Neo4j是一個高性能的,NOSQL圖形數據庫,它將結構化數據存儲在網絡上而不是表中。
    spring-boot-starter-redis:支持Redis鍵值存儲數據庫,包括spring-redis。
    spring-boot-starter-data-rest:通過spring-data-rest-webmvc,支持通過REST暴露Spring Data數據倉庫。
    spring-boot-starter-data-solr:支持Apache Solr搜索平臺,包括spring-data-solr。
    spring-boot-starter-freemarker:支持FreeMarker模板引擎。
    spring-boot-starter-groovy-templates:支持Groovy模板引擎。
    spring-boot-starter-hateoas:通過spring-hateoas支持基於HATEOAS的RESTful Web服務。
    spring-boot-starter-integration:支持通用的spring-integration模塊。
    spring-boot-starter-jdbc:支持JDBC數據庫。
    spring-boot-starter-jersey:支持Jersey RESTful Web服務框架。
    spring-boot-starter-hornetq:通過HornetQ支持JMS。
    spring-boot-starter-jta-atomikos:通過Atomikos支持JTA分佈式事務處理。
    spring-boot-starter-jta-bitronix:通過Bitronix支持JTA分佈式事務處理。
    spring-boot-starter-mail:支持javax.mail模塊。
    spring-boot-starter-mobile:支持spring-mobile。
    spring-boot-starter-mustache:支持Mustache模板引擎。
    spring-boot-starter-security:支持spring-security。
    spring-boot-starter-social-facebook:支持spring-social-facebook
    spring-boot-starter-social-linkedin:支持pring-social-linkedin
    spring-boot-starter-social-twitter:支持pring-social-twitter
    spring-boot-starter-test:支持常規的測試依賴,包括JUnit、Hamcrest、Mockito以及spring-test模塊。
    spring-boot-starter-thymeleaf:支持Thymeleaf模板引擎,包括與Spring的集成。
    spring-boot-starter-velocity:支持Velocity模板引擎。
    spring-boot-starter-web:支持全棧式Web開發,包括Tomcat和spring-webmvc。
    spring-boot-starter-websocket:支持WebSocket開發。
    spring-boot-starter-ws:支持Spring Web Services。

Spring Boot在進行SpringApplication對象實例化時會加載META-INF/spring.factories文件,將該配置文件中的配置載入到Spring容器,進行自動配置。

1 源碼分析

首先進入到啓動Spring Boot項目代碼SpringApplication.run(App.class, args)的源碼下:

  1. 程序清單:org/springframework/boot/SpringApplication

  2. public static ConfigurableApplicationContext run(Object[] sources, String[] args) {

  3.    return new SpringApplication(sources).run(args);

  4. }            

可以看到run方法實際上在創建SpringApplication對象實例,進入到創建SpringApplication對象實例代碼中去:

  1. 程序清單:org/springframework/boot/SpringApplication

  2. public SpringApplication(Object... sources) {

  3.    initialize(sources);

  4. }

接下來就是調用initialize(sources)方法,進入到該方法源碼如下:

  1. 程序清單:org/springframework/boot/SpringApplication

  2. @SuppressWarnings({ "unchecked", "rawtypes" })

  3. private void initialize(Object[] sources) {

  4.    if (sources != null && sources.length > 0) {

  5.        this.sources.addAll(Arrays.asList(sources));

  6.    }

  7.    this.webEnvironment = deduceWebEnvironment();

  8.    setInitializers((Collection) getSpringFactoriesInstances(

  9.            ApplicationContextInitializer.class));

  10.    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));

  11.    this.mainApplicationClass = deduceMainApplicationClass();

  12. }

initialize方法中調用了getSpringFactoriesInstances方法,代碼如下:

  1. 程序清單:org/springframework/boot/SpringApplication

  2. private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type,

  3.        Class<?>[] parameterTypes, Object... args) {

  4.    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

  5.    // Use names and ensure unique to protect against duplicates

  6.    Set<String> names = new LinkedHashSet<String>(

  7.            SpringFactoriesLoader.loadFactoryNames(type, classLoader));

  8.    List<T> instances = createSpringFactoriesInstances(type, parameterTypes,

  9.            classLoader, args, names);

  10.    AnnotationAwareOrderComparator.sort(instances);

  11.    return instances;

  12. }

在getSpringFactoriesInstances中又調用了loadFactoryNames方法,繼續進入到該方法中,查看源碼如下:

  1. 程序清單:org/springframework/boot.SpringApplication

  2. public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {

  3.    String factoryClassName = factoryClass.getName();

  4.    try {

  5. Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :

  6. ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));

  7.        List<String> result = new ArrayList<String>();

  8.        while (urls.hasMoreElements()) {

  9.            URL url = urls.nextElement();

  10.            Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));

  11.            String factoryClassNames = properties.getProperty(factoryClassName);

  12.            result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));

  13.        }

  14.        return result;

  15.    }

  16.    catch (IOException ex) {

  17.        throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() +

  18.                "] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);

  19.    }

  20. }

在上述源碼中可以查看到加載了一個常量:FACTORIESRESOURCELOCATION,查看該常量的源碼如下:

  1. /**

  2. * The location to look for factories.

  3. * <p>Can be present in multiple JAR files.

  4. */

  5. public  static  final  String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

從該源碼中可以看出,最終Spring Boot是通過加載META-INF/spring.factories 文件來進行自動配置的。其所在位置如下圖所示。

2.9 spring.factories位置.png

2 spring.factories分析

Spring factories內容如下:

  1. # Initializers

  2. org.springframework.context.ApplicationContextInitializer=\

  3. org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\

  4. org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer

  5. # Application Listeners

  6. org.springframework.context.ApplicationListener=\

  7. org.springframework.boot.autoconfigure.BackgroundPreinitializer

  8. # Auto Configuration Import Listeners

  9. org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\

  10. org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener

  11. # Auto Configuration Import Filters

  12. org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\

  13. org.springframework.boot.autoconfigure.condition.OnClassCondition

  14. # Auto Configure

  15. org.springframework.boot.autoconfigure.EnableAutoConfiguration=\

  16. org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\

  17. org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\

  18. org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\

  19. org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\

  20. org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\

  21. org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\

  22. org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\

  23. org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\

  24. org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\

  25. org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\

  26. org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\

  27. org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\

  28. org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\

  29. org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\

  30. org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\

  31. org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\

  32. org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\

  33. org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\

  34. org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\

  35. org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\

  36. org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,\

  37. org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\

  38. org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\

  39. org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\

  40. org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\

  41. org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\

  42. org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\

  43. org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\

  44. org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\

  45. org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\

  46. org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\

  47. org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\

  48. org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\

  49. org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\

  50. org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\

  51. org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\

  52. org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\

  53. org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\

  54. org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\

  55. org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\

  56. org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\

  57. org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\

  58. org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\

  59. org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\

  60. org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\

  61. org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\

  62. org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\

  63. org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\

  64. org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\

  65. org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\

  66. org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\

  67. org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\

  68. org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\

  69. org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\

  70. org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\

  71. org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\

  72. org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\

  73. org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\

  74. org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\

  75. org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\

  76. org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\

  77. org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\

  78. org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoConfiguration,\

  79. org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,\

  80. org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\

  81. org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\

  82. org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\

  83. org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\

  84. org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration,\

  85. org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,\

  86. org.springframework.boot.autoconfigure.security.SecurityFilterAutoConfiguration,\

  87. org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,\

  88. org.springframework.boot.autoconfigure.security.oauth2.OAuth2AutoConfiguration,\

  89. org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\

  90. org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\

  91. org.springframework.boot.autoconfigure.social.SocialWebAutoConfiguration,\

  92. org.springframework.boot.autoconfigure.social.FacebookAutoConfiguration,\

  93. org.springframework.boot.autoconfigure.social.LinkedInAutoConfiguration,\

  94. org.springframework.boot.autoconfigure.social.TwitterAutoConfiguration,\

  95. org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\

  96. org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\

  97. org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\

  98. org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\

  99. org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\

  100. org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration,\

  101. org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,\

  102. org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration,\

  103. org.springframework.boot.autoconfigure.web.HttpEncodingAutoConfiguration,\

  104. org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration,\

  105. org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration,\

  106. org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration,\

  107. org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration,\

  108. org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\

  109. org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration,\

  110. org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration,\

  111. org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration

  112. # Failure analyzers

  113. org.springframework.boot.diagnostics.FailureAnalyzer=\

  114. org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,\

  115. org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer,\

  116. org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer

  117. # Template availability providers

  118. org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\

  119. org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,\

  120. org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider,\

  121. org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,\

  122. org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,\

  123. org.springframework.boot.autoconfigure.web.JspTemplateAvailabilityProvider

在spring.factories中可以看出web開發的自動配置類是:org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,在這個類中就自動實現了Sprng MVC的配置。現在以Spring MVC的配置如下:

  1. <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">

  2. <property name="prefix" value="/WEB-INF/jsp/"/>

  3. <property name="suffix" value=".jsp"/>

  4. </bean>

爲例看Spring Boot是如何實現該自動配置的:

(1) 查詢WebMvcAutoConfiguration的源碼如下:

@Configuration@ConditionalOnWebApplication@ConditionalOnClass({ Servlet.class, DispatcherServlet.class,        WebMvcConfigurerAdapter.class })@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,        ValidationAutoConfiguration.class })public class WebMvcAutoConfiguration {

其中@ConditionalOnClass是一個條件註解,意思就是隻有當前項目運行環境中有Servlet類,並且有DispatcherServlet類以及WebMvcConfigurerAdapter類時(說明本項目是需要集成Spring MVC的),,Spring Boot纔會初始化WebMvcAutoConfiguration進行自動配置。 (2) 自動配置試圖解析器ViewResolver。 在WebMvcAutoConfiguration類下找到以下源碼:

@Bean@ConditionalOnMissingBeanpublic InternalResourceViewResolver defaultViewResolver() {    InternalResourceViewResolver resolver = new InternalResourceViewResolver();    resolver.setPrefix(this.mvcProperties.getView().getPrefix());    resolver.setSuffix(this.mvcProperties.getView().getSuffix());    return resolver;}

@Bean是在這裏定義了一個Bean對象InternalResourceViewResolver,以前我們是通過標籤來定義的。 @CoditionalOnMissingBean是一個條件註解,是當 前環境下沒有這個Bean的時候纔會創建該bean。 方法的返回值即是InternalResourceViewResolver,即是我們需要的對象,那麼視圖解析器中前綴和後綴Spring Boot是如何實現自動配置的呢?

resolver.setPrefix(this.mvcProperties.getView().getPrefix());resolver.setSuffix(this.mvcProperties.getView().getSuffix());該源碼會找到一個View對象:public static class View {    /**     * Spring MVC view prefix.     */    private String prefix;    /**     * Spring MVC view suffix.     */    private String suffix;    public String getPrefix() {        return this.prefix;    }    public void setPrefix(String prefix) {        this.prefix = prefix;    }    public String getSuffix() {        return this.suffix;    }    public void setSuffix(String suffix) {        this.suffix = suffix;    }}

View對象則會通過獲取prefix,suffix加載視圖解析器需要的前綴和後綴,該參數的值是可以通過全局配置文件來指定前綴和後綴的,配置如下:

spring.mvc.view.prefix= # Spring MVC view prefix.
spring.mvc.view.suffix= # Spring MVC view suffix.


0.jpg

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章