我們都知道springboot可以簡化Spring框架帶來的大量XML配置以及復雜的依賴管理,讓開發人員可以更加關注業務邏輯的開發。
怎么簡化我們的xml配置
Spring Boot更多的是采用Java Config的方式,對Spring進行配置。
我們不僅可以通過它提供的properties
或者yaml
來設置一些基礎的配置信息。如:server.port 等。還可以很輕松的實現多環境多配置文件的啟動,打包。springboot學習之maven多環境打包的幾種方式
我們還可以自定義配置文件來做我們自己的業務邏輯。如:配置系統常量,第三方數據管理等等。
我們自己很多時候會寫一些自定義的配置文件(基于java Config),寫這些配置的時候我們會用到很多注解。正確的運用這些注解會給我們的開發帶來方便。但是錯誤的使用也會造成很嚴重的后果。
配置文件注解詳解
我們以freemarker為例來給大家說下springboot配置文件注解的解釋,大家可以直接看代碼的注釋。
看一下它的自動化配置類:
@Configuration // 使用Configuration注解,自動構造一些內部定義的bean
@ConditionalOnClass({ freemarker.template.Configuration.class,
FreeMarkerConfigurationFactory.class }) // 需要freemarker.template.Configuration和FreeMarkerConfigurationFactory這兩個類存在在classpath中才會進行自動配置
@AutoConfigureAfter(WebMvcAutoConfiguration.class) // 本次自動配置需要依賴WebMvcAutoConfiguration這個配置類配置之后觸發。這個WebMvcAutoConfiguration內部會配置很多Wen基礎性的東西,比如RequestMappingHandlerMapping、RequestMappingHandlerAdapter等
@EnableConfigurationProperties(FreeMarkerProperties.class) // 使用FreeMarkerProperties類中的配置
public class FreeMarkerAutoConfiguration {
private static final Log logger = LogFactory
.getLog(FreeMarkerAutoConfiguration.class);
@Autowired
private ApplicationContext applicationContext;
@Autowired
private FreeMarkerProperties properties;
@PostConstruct // 構造之后調用的方法,組要檢查模板位置是否存在
public void checkTemplateLocationExists() {
if (this.properties.isCheckTemplateLocation()) {
TemplateLocation templatePathLocation = null;
List<TemplateLocation> locations = new ArrayList<TemplateLocation>();
for (String templateLoaderPath : this.properties.getTemplateLoaderPath()) {
TemplateLocation location = new TemplateLocation(templateLoaderPath);
locations.add(location);
if (location.exists(this.applicationContext)) {
templatePathLocation = location;
break;
}
}
if (templatePathLocation == null) {
logger.warn("Cannot find template location(s): " + locations
+ " (please add some templates, "
+ "check your FreeMarker configuration, or set "
+ "spring.freemarker.checkTemplateLocation=false)");
}
}
}
protected static class FreeMarkerConfiguration {
@Autowired
protected FreeMarkerProperties properties;
protected void applyProperties(FreeMarkerConfigurationFactory factory) {
factory.setTemplateLoaderPaths(this.properties.getTemplateLoaderPath());
factory.setPreferFileSystemAccess(this.properties.isPreferFileSystemAccess());
factory.setDefaultEncoding(this.properties.getCharsetName());
Properties settings = new Properties();
settings.putAll(this.properties.getSettings());
factory.setFreemarkerSettings(settings);
}
}
@Configuration
@ConditionalOnNotWebApplication // 非Web項目的自動配置
public static class FreeMarkerNonWebConfiguration extends FreeMarkerConfiguration {
@Bean
@ConditionalOnMissingBean
public FreeMarkerConfigurationFactoryBean freeMarkerConfiguration() {
FreeMarkerConfigurationFactoryBean freeMarkerFactoryBean = new FreeMarkerConfigurationFactoryBean();
applyProperties(freeMarkerFactoryBean);
return freeMarkerFactoryBean;
}
}
@Configuration // 自動配置的類
@ConditionalOnClass(Servlet.class) // 需要運行在Servlet容器下
@ConditionalOnWebApplication // 需要在Web項目下
public static class FreeMarkerWebConfiguration extends FreeMarkerConfiguration {
@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") // 沒有配置freeMarkerViewResolver這個bean的話,會自動構造一個freeMarkerViewResolver
@ConditionalOnProperty(name = "spring.freemarker.enabled", matchIfMissing = true) // 配置文件中開關開啟的話,才會構造
public FreeMarkerViewResolver freeMarkerViewResolver() {
// 構造了freemarker的ViewSolver,這就是一開始我們分析的為什么沒有設置ViewResolver,但是最后卻還是存在的原因
FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
this.properties.applyToViewResolver(resolver);
return resolver;
}
}
}
freemarker對應的配置類:
@ConfigurationProperties(prefix = "spring.freemarker") // 使用配置文件中以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"; // 默認后綴
...
}
下面是官網上的freemarker配置:
# FREEMARKER (FreeMarkerAutoConfiguration)
spring.freemarker.allow-request-override=false # Set whether HttpServletRequest attributes are allowed to override (hide) controller generated model attributes of the same name.
spring.freemarker.allow-session-override=false # Set whether HttpSession attributes are allowed to override (hide) controller generated model attributes of the same name.
spring.freemarker.cache=false # Enable template caching.
spring.freemarker.charset=UTF-8 # Template encoding.
spring.freemarker.check-template-location=true # Check that the templates location exists.
spring.freemarker.content-type=text/html # Content-Type value.
spring.freemarker.enabled=true # Enable MVC view resolution for this technology.
spring.freemarker.expose-request-attributes=false # Set whether all request attributes should be added to the model prior to merging with the template.
spring.freemarker.expose-session-attributes=false # Set whether all HttpSession attributes should be added to the model prior to merging with the template.
spring.freemarker.expose-spring-macro-helpers=true # Set whether to expose a RequestContext for use by Spring's macro library, under the name "springMacroRequestContext".
spring.freemarker.prefer-file-system-access=true # Prefer file system access for template loading. File system access enables hot detection of template changes.
spring.freemarker.prefix= # Prefix that gets prepended to view names when building a URL.
spring.freemarker.request-context-attribute= # Name of the RequestContext attribute for all views.
spring.freemarker.settings.*= # Well-known FreeMarker keys which will be passed to FreeMarker's Configuration.
spring.freemarker.suffix= # Suffix that gets appended to view names when building a URL.
spring.freemarker.template-loader-path=classpath:/templates/ # Comma-separated list of template paths.
spring.freemarker.view-names= # White list of view names that can be resolved.
總結
springboot內部提供了很多自動化配置的類,這些類會判斷classpath中是否存在自己需要的那個類,如果存在則會自動配置相關的配置,否則就不會自動配置。根據自己的實際開發環境合理使用配置文件才能事半功倍!