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.