首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Spring Boot 整合 FreeMarker TemplateDirectiveModel 依賴注入失效的解決方案

     編輯:程式設計疑難解答

現象

自定義 TemplateDirectiveModel 實現類中注入 TestService 為 null,導致指令執行拋 NPE。

根因

TemplateDirectiveModel 實例由 FreeMarker 引擎創建,**不受 Spring 容器管理**,因此 @Autowired / @Service 等註解不生效。

解決方案:手動從 ApplicationContext 獲取 Bean

@Component
public class MyDirective implements TemplateDirectiveModel {

    @Override
    public void execute(Environment env, Map params, TemplateModel[] loopVars,
                        TemplateDirectiveBody body) throws TemplateException, IOException {
        // 從靜態持有器或實現 ApplicationContextAware 獲取上下文
        TestService service = SpringContextHolder.getBean(TestService.class);
        String result = service.getOne();
        // 輸出到模板...
    }
}

// 輔助類:實現 ApplicationContextAware 靜態持有上下文
@Component
class SpringContextHolder implements ApplicationContextAware {
    private static ApplicationContext context;
    @Override public void setApplicationContext(ApplicationContext ctx) { context = ctx; }
    public static <T> T getBean(Class<T> clazz) { return context.getBean(clazz); }
}

替代方案:配置 SharedVariable 讓 Spring 管理指令實例

@Configuration
public class FreemarkerConfig implements FreemarkerConfigurer {
    @Autowired private MyDirective myDirective;

    @Override
    public void configure(Configuration cfg) {
        cfg.setSharedVariable("myDirective", myDirective); // Spring 管理實例,注入生效
    }
}

模板中直接用 @myDirective() 調用。

核心原則

Spring Boot 所有需注入依賴的對象,必須由 Spring 容器創建與管理。凡框架自行實例化的對象(FreeMarker 指令、Quartz Job、JPA Listener 等),均需通過 ApplicationContextAware 或 @Configurable(需 AspectJ 織入)橋接容器。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved