You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Spring Boot项目动态跨工程互用FreeMarker模板?

我之前遇到过几乎一模一样的问题,核心原因是默认的模板加载器配置没有正确覆盖本地和依赖包的templates路径,而且模板加载器的路径映射有问题。下面是我验证过的可行解决方案:

1. 替换默认配置,手动构建多源模板加载器

原来的FreeMarkerConfigurationFactoryBean可能因为本地templates目录的存在,优先使用了FileTemplateLoader——这个加载器只能读取本地文件系统的资源,根本访问不到依赖jar包里的templates。同时自动生成的ClassTemplateLoader路径设置不对,导致找不到jar里的模板。我们需要手动配置加载器,确保同时扫描本地和jar包中的classpath:/templates/目录:

@Bean
public FreeMarkerConfigurer freeMarkerConfigurer() {
    FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
    // 替换为你项目实际使用的Freemarker版本
    Configuration freemarkerConfig = new Configuration(Configuration.VERSION_2_3_32);

    // 配置两个ClassTemplateLoader:
    // 1. 从当前类的上下文加载本地项目的templates
    // 2. 从系统类加载器根目录加载所有依赖jar中的templates
    ClassTemplateLoader localTemplateLoader = new ClassTemplateLoader(this.getClass(), "/templates/");
    ClassTemplateLoader jarTemplateLoader = new ClassTemplateLoader(ClassLoader.getSystemClassLoader(), "/templates/");

    // 组合成多源加载器,顺序可以根据需求调整(优先本地还是jar包)
    MultiTemplateLoader multiLoader = new MultiTemplateLoader(new TemplateLoader[]{localTemplateLoader, jarTemplateLoader});

    freemarkerConfig.setTemplateLoader(multiLoader);
    freemarkerConfig.setDefaultEncoding("UTF-8");
    freemarkerConfig.setObjectWrapper(new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_32).build());
    // 可选:添加其他Freemarker配置,比如自动导入、日期格式等

    configurer.setConfiguration(freemarkerConfig);
    return configurer;
}

2. 确认模板导入路径的正确性

你的模板里用的<#import "/feature3/f3page.ftl" as f3>这个写法是对的——绝对路径/会从模板加载器的根目录(也就是我们配置的/templates/)开始查找,不管是本地Project A还是依赖Project B里的/templates/feature3/f3page.ftl都能匹配到。

3. 验证依赖包的模板是否正确打包

确保Project B的src/main/resources/templates目录被正确打包到jar中。Maven默认会打包这个目录,但如果Project B的pom.xml有自定义的<resources>配置,一定要检查是否包含了该目录:

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*</include>
            </includes>
        </resource>
    </resources>
</build>

4. 清理并重新构建项目

有时候target目录里的旧资源会干扰加载,先清理Project A的target目录,再执行mvn clean install,确保依赖的Project B jar是最新的,并且包含了所有模板文件。

补充说明为什么原来的配置不行

当你设置setTemplateLoaderPath("classpath:/templates/")并开启setPreferFileSystemAccess(false)时,Spring的FreeMarkerConfigurationFactoryBean可能仍然因为本地templates目录存在(在target/classes下),优先使用了FileTemplateLoader,而这个加载器无法读取jar中的资源。同时从报错信息能看到,自动配置的ClassTemplateLoader的basePackagePath是空的,导致它会去类路径根目录找/feature3/f3page.ftl,而不是正确的/templates/feature3/f3page.ftl,自然找不到目标模板。

内容的提问来源于stack exchange,提问作者CtrlAltMe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:16:46