官术网_书友最值得收藏!

3.4 FreeMarkerAutoConfiguration實例分析

本節通過FreeMarkerAutoConfiguration實例來分析Spring Boot中集成Freemarker模板引擎的整個自動配置的過程。

3.4.1 spring-boot-starter-freemarker工程

spring-boot-starter-freemarker工程是實現Free Marker模板引擎自動配置的啟動工程,其目錄結構如下:

        .
        ├── pom.xml
        ├── spring-boot-starter-freemarker.iml
        └── src
            └── main
                └── resources
                    └── META-INF
                            └── spring.provides
          4 directories, 3 files

我們可以看出,這個工程沒有任何Java代碼,只有兩個文件:pom.xml與spring.provides,其中,spring.provides文件如下:

        provides: freemarker, spring-context-support

主要是給這個starter起個好區分的名字。

Spring Boot通過starter對項目的依賴進行統一管理.starter利用了Maven的傳遞依賴解析機制,把常用庫聚合在一起,組成了針對特定功能而定制的依賴starter。

我們可以使用IDEA提供的Maven依賴圖分析的功能,得到spring-boot-starter-freemarker依賴的module,如圖3-4所示。

圖3-4 spring-boot-starter-freemarker依賴的module

從圖中我們可以看出其中的依賴關系。

當Spring Boot Application中自動配置EnableAutoConfiguration的相關類執行完畢之后,Spring Boot會進一步解析對應類的配置信息。如果我們配置了spring-boot-starter-freemarker, Maven就會通過這個starter所依賴的spring-boot-autoconfigure,自動傳遞到spring-boot-autoconfigure工程中。

3.4.2 spring-boot-autoconfigure工程

我們來簡單分析一下spring-boot-autoconfigure工程中關于FreeMarker自動配置的邏輯實現。FreeMarker自動配置的入口類是:

        org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration

這個配置類中導入了FreeMarkerServletWebConfiguration、FreeMarkerReactiveWebCon-figuration、FreeMarkerNonWebConfiguration配置類:

        @Configuration
        @ConditionalOnClass({ freemarker.template.Configuration.class,
                FreeMarkerConfigurationFactory.class })
        @EnableConfigurationProperties(FreeMarkerProperties.class)
        @Import({ FreeMarkerServletWebConfiguration.class,
                FreeMarkerReactiveWebConfiguration.class, FreeMarkerNonWebConfigura
                        tion.class })
            public class FreeMarkerAutoConfiguration

其中:

?@Configuration是org.springframework.context.annotation包里面的注解。我們已經知道用@Configuration注解該類,等價于XML中配置Bean;用@Bean標注方法等價于XML中配置Bean。

?@ConditionalOnClass是org.springframework.boot.autoconfigure.condition包里面的注解。意思是當類路徑下有指定的類的條件下,才會去注冊被標注的類為一個Bean。在上面的代碼中的意思就是,當類路徑中有:

            freemarker.template.Configuration.class
            FreeMarkerConfigurationFactory.class

這兩個類的時候,才會去配置FreeMarkerAutoConfiguration。

?@EnableConfigurationProperties,表示啟動對FreeMarkerProperties.class的內嵌配置支持,自動將FreeMarkerProperties注冊為一個Bean。這個FreeMarkerProperties類里面就是關于FreeMarker屬性的配置:

        @ConfigurationProperties(prefix = "spring.freemarker")
        public class FreeMarkerProperties extends AbstractTemplateViewResolverProperties {
            public static final String DEFAULT_TEMPLATE_LOADER_PATH = "classpath:/
                templates/";
            public static final String DEFAULT_PREFIX = "";
            public static final String DEFAULT_SUFFIX = ".ftl";
            …
        }

接下來,我們來看一下FreeMarkerServletWebConfiguration這個類。該類主要是用于配置基于servlet web context的Freemarker的配置。這個類的代碼如下:

        @Configuration
        @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
        @ConditionalOnClass({ Servlet.class, FreeMarkerConfigurer.class })
        @AutoConfigureAfter(WebMvcAutoConfiguration.class)
        class FreeMarkerServletWebConfiguration extends AbstractFreeMarkerConfiguration {
            protected FreeMarkerServletWebConfiguration(FreeMarkerProperties pro
                perties) {
                super(properties);
            }
            @Bean
            @ConditionalOnMissingBean(FreeMarkerConfig.class)
            public FreeMarkerConfigurer freeMarkerConfigurer() {
                  FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
                  applyProperties(configurer);
                  return configurer;
              }
              @Bean
              public freemarker.template.Configuration freeMarkerConfiguration(
                      FreeMarkerConfig configurer) {
                  return configurer.getConfiguration();
              }
              @Bean
              @ConditionalOnMissingBean(name = "freeMarkerViewResolver")
              @ConditionalOnProperty(name = "spring.freemarker.enabled", matchIfMis
                  sing = true)
              public FreeMarkerViewResolver freeMarkerViewResolver() {
                  FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
                  getProperties().applyToMvcViewResolver(resolver);
                  return resolver;
              }
              @Bean
              @ConditionalOnMissingBean
              @ConditionalOnEnabledResourceChain
              public ResourceUrlEncodingFilter resourceUrlEncodingFilter() {
                  return new ResourceUrlEncodingFilter();
              }
          }

其中:

1)當該應用是基于Servlet的Web應用時,Spring容器內有Servlet.class、FreeMarker Configurer.class類實例存在。

2)Spring容器中不存在freeMarkerViewResolver的Bean。

3)應用程序的屬性配置文件中沒有匹配到"spring.freemarker.enabled"。

當1)2)3)三個條件都滿足,則初始化freeMarkerViewResolver這個Bean。

我們也可以自定義自己的starter,以及實現對應的@MyEnableAutoConfiguration。Spring Boot有很多第三方starter,其自動配置的原理基本都是這樣,比如mybatis-spring-boot-starter的MybatisAutoConfiguration,源碼在如下地址:https://github.com/mybatis/spring-boot-starter,閱讀源碼可加深理解。

主站蜘蛛池模板: 旺苍县| 涡阳县| 无为县| 龙南县| 定结县| 苏州市| 台北市| 辽源市| 石狮市| 两当县| 连云港市| 罗定市| 定边县| 泰来县| 武汉市| 眉山市| 昂仁县| 雷波县| 湘潭市| 安吉县| 林西县| 榆树市| 兴仁县| 井研县| 杭州市| 独山县| 二连浩特市| 新巴尔虎右旗| 山阴县| 浑源县| 黑水县| 朝阳县| 郁南县| 平谷区| 白朗县| 翁牛特旗| 板桥市| 临洮县| 固镇县| 西华县| 视频|