- Spring Boot開發實戰
- 陳光劍
- 926字
- 2019-01-05 10:00:26
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,閱讀源碼可加深理解。
- 極簡算法史:從數學到機器的故事
- Microsoft Application Virtualization Cookbook
- Learn to Create WordPress Themes by Building 5 Projects
- Learning ASP.NET Core 2.0
- 跟小海龜學Python
- Processing創意編程指南
- 大話Java:程序設計從入門到精通
- Practical GIS
- QlikView Unlocked
- Unity 5 Game Optimization
- INSTANT EaselJS Starter
- Cocos2D Game Development Essentials
- Python High Performance(Second Edition)
- VB語言程序設計實驗教程
- Hands-On Full Stack Development with Angular 5 and Firebase