自定義 TemplateDirectiveModel 實現類中注入 TestService 為 null,導致指令執行拋 NPE。
TemplateDirectiveModel 實例由 FreeMarker 引擎創建,**不受 Spring 容器管理**,因此 @Autowired / @Service 等註解不生效。
@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); }
}
@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 織入)橋接容器。