Example
In this example, extra FreeMarker template engine is added into Spring MVC project using Thymeleaf template engine. A 'hello world' page is displayed using this new added engine.
First get a copy of my notice board example application. Add following line into pom.xml to include FreeMarker template engine into project.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
Add a FreeMarker template, as 'resources/templates/public/freemarker_test.ftl'.
<html>
<head>
<title>${title}</title>
</head>
<body>
<div>${body}</div>
</body>
</html>
Add a new function into info.saladlam.example.spring.noticeboard.controller.PublicController controller.
public class PublicController {
// ...
@GetMapping("/freemarker_test")
public String freemarkerTest(Model model) {
model.addAttribute("title", "FreeMarker test page");
model.addAttribute("body", "Hello world!");
return "public/freemarker_test";
}
}
Start application and in browser to open http://localhost:8080/freemarker_test. As result 'Hello world!' is show.
# What happen behind?
When application started. Following org.springframework.web.servlet.ViewResolver bean is created by Spring Boot.
- org.thymeleaf.spring5.view.ThymeleafViewResolver
- org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver
org.springframework.web.servlet.DispatcherServlet instance is created. During initialization, method initViewResolvers() is called.
if (this.detectAllViewResolvers) {
// Find all ViewResolvers in the ApplicationContext, including ancestor contexts.
Map<String, ViewResolver> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false);
if (!matchingBeans.isEmpty()) {
this.viewResolvers = new ArrayList<>(matchingBeans.values());
// We keep ViewResolvers in sorted order.
AnnotationAwareOrderComparator.sort(this.viewResolvers);
}
}
// ...
Code listed above shows that all bean with ViewResolver interface is provided by BeanFactory.
When method freemarkerTest() in PublicController being called, string 'public/freemarker_test' is return. This string will pass into org.thymeleaf.spring5.view.ThymeleafViewResolver. Since no Thymeleaf template withi this name is defined, so null is returned. Then pass into org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver and instance with org.springframework.web.servlet.View interface is returned.