我们都知道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中是否存在自己需要的那个类,如果存在则会自动配置相关的配置,否则就不会自动配置。根据自己的实际开发环境合理使用配置文件才能事半功倍!