Spring Boot AutoConfigure provides auto-configuration capabilities that automatically configure Spring applications based on jar dependencies present on the classpath
—
Spring Boot AutoConfigure provides infrastructure for detecting and configuring template engines, allowing automatic discovery of template availability and location-based template resolution.
import org.springframework.boot.autoconfigure.template.*;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;Functional interface for indicating the availability of view templates for a particular templating engine.
@FunctionalInterface
public interface TemplateAvailabilityProvider {
/**
* Returns true if a template is available for the given view.
*
* @param view the view name to check
* @param environment the environment for property resolution
* @param classLoader the class loader for resource loading
* @param resourceLoader the resource loader for template location
* @return true if the template is available
*/
boolean isTemplateAvailable(
String view,
Environment environment,
ClassLoader classLoader,
ResourceLoader resourceLoader
);
}Collection of TemplateAvailabilityProvider beans that can be used to check which templating engine supports a given view. Caches responses unless spring.template.provider.cache is set to false.
public class TemplateAvailabilityProviders {
/**
* Create a new TemplateAvailabilityProviders instance.
*
* @param applicationContext the application context
*/
public TemplateAvailabilityProviders(ApplicationContext applicationContext);
/**
* Get all registered template availability providers.
*
* @return list of providers in order
*/
public List<TemplateAvailabilityProvider> getProviders();
/**
* Check if a template is available for the given view using any registered provider.
*
* @param view the view name
* @param environment the environment
* @param classLoader the class loader
* @param resourceLoader the resource loader
* @return true if any provider reports the template as available
*/
public boolean isTemplateAvailable(
String view,
Environment environment,
ClassLoader classLoader,
ResourceLoader resourceLoader
);
}Abstract base class for template availability providers that check for templates at specific file paths.
public abstract class PathBasedTemplateAvailabilityProvider
implements TemplateAvailabilityProvider {
/**
* Create a new PathBasedTemplateAvailabilityProvider.
*
* @param className the class name to check for on the classpath
* @param propertiesClass the configuration properties class
* @param propertyPrefix the configuration property prefix
*/
public PathBasedTemplateAvailabilityProvider(
String className,
Class<? extends TemplateAvailabilityProperties> propertiesClass,
String propertyPrefix
);
/**
* Check if a template is available at the configured path.
*/
public boolean isTemplateAvailable(
String view,
Environment environment,
ClassLoader classLoader,
ResourceLoader resourceLoader
);
/**
* Get the prefix for template locations.
* Subclasses should override to provide custom prefix.
*
* @return the template location prefix
*/
public String getPrefix();
/**
* Set the prefix for template locations.
*
* @param prefix the prefix to set
*/
public void setPrefix(String prefix);
/**
* Get the suffix for template files.
* Subclasses should override to provide custom suffix.
*
* @return the template file suffix
*/
public String getSuffix();
/**
* Set the suffix for template files.
*
* @param suffix the suffix to set
*/
public void setSuffix(String suffix);
}Contains a location that templates can be loaded from. Used to verify template directory existence.
public class TemplateLocation {
/**
* Create a new TemplateLocation.
*
* @param path the template location path
*/
public TemplateLocation(String path);
/**
* Check if the template location exists using the given resolver.
*
* @param resolver the resource pattern resolver
* @return true if the location exists
*/
public boolean exists(ResourcePatternResolver resolver);
/**
* Get the string representation of the location.
*/
public String toString();
}import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;
@Component
public class CustomTemplateAvailabilityProvider
implements TemplateAvailabilityProvider {
@Override
public boolean isTemplateAvailable(
String view,
Environment environment,
ClassLoader classLoader,
ResourceLoader resourceLoader) {
String prefix = environment.getProperty(
"spring.custom.template.prefix",
"classpath:/templates/"
);
String suffix = environment.getProperty(
"spring.custom.template.suffix",
".custom"
);
String templatePath = prefix + view + suffix;
Resource resource = resourceLoader.getResource(templatePath);
return resource.exists() && resource.isReadable();
}
}import org.springframework.boot.autoconfigure.template.PathBasedTemplateAvailabilityProvider;
import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider;
public class MyTemplateAvailabilityProvider
extends PathBasedTemplateAvailabilityProvider {
public MyTemplateAvailabilityProvider() {
super("com.example.MyTemplateEngine",
TemplateAvailabilityProvider.class,
"spring.my-template");
setPrefix("classpath:/my-templates/");
setSuffix(".mt");
}
}import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
@Service
public class TemplateService {
private final TemplateAvailabilityProviders providers;
private final Environment environment;
private final ResourceLoader resourceLoader;
public TemplateService(
ApplicationContext applicationContext,
Environment environment,
ResourceLoader resourceLoader) {
this.providers = new TemplateAvailabilityProviders(applicationContext);
this.environment = environment;
this.resourceLoader = resourceLoader;
}
public boolean hasTemplate(String viewName) {
return providers.isTemplateAvailable(
viewName,
environment,
getClass().getClassLoader(),
resourceLoader
);
}
public List<String> findAvailableTemplates(List<String> viewNames) {
return viewNames.stream()
.filter(this::hasTemplate)
.collect(Collectors.toList());
}
}import org.springframework.boot.autoconfigure.template.TemplateLocation;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
public class TemplateLocationValidator {
public boolean validateTemplateDirectory(String path) {
TemplateLocation location = new TemplateLocation(path);
ResourcePatternResolver resolver =
new PathMatchingResourcePatternResolver();
return location.exists(resolver);
}
public void checkCommonLocations() {
String[] commonLocations = {
"classpath:/templates/",
"classpath:/templates/thymeleaf/",
"classpath:/templates/freemarker/",
"classpath:/templates/mustache/"
};
ResourcePatternResolver resolver =
new PathMatchingResourcePatternResolver();
for (String path : commonLocations) {
TemplateLocation location = new TemplateLocation(path);
if (location.exists(resolver)) {
System.out.println("Found template location: " + path);
}
}
}
}import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.ModelAndView;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Map;
@Component
public class CustomErrorViewResolver implements ErrorViewResolver {
private final TemplateAvailabilityProviders providers;
public CustomErrorViewResolver(ApplicationContext applicationContext) {
this.providers = new TemplateAvailabilityProviders(applicationContext);
}
@Override
public ModelAndView resolveErrorView(
HttpServletRequest request,
HttpStatus status,
Map<String, Object> model) {
String errorView = "error/" + status.value();
if (hasTemplate(errorView)) {
return new ModelAndView(errorView, model);
}
return null; // Fall back to default error handling
}
private boolean hasTemplate(String view) {
return providers.isTemplateAvailable(
view,
applicationContext.getEnvironment(),
getClass().getClassLoader(),
applicationContext
);
}
}spring:
template:
provider:
cache: false # Disable caching for development# Thymeleaf
spring:
thymeleaf:
prefix: classpath:/templates/
suffix: .html
cache: false # Disable for development
# FreeMarker
spring:
freemarker:
template-loader-path: classpath:/templates/
suffix: .ftl
cache: false
# Mustache
spring:
mustache:
prefix: classpath:/templates/
suffix: .mustache
cache: falseorg.springframework.core.Ordered for custom providers to control precedencetemplates/error/