setVelocity 引擎无法应用于 org.springframework.ui.velocity.VelocityEngineFactoryBean

setVelocity engine cannot be applied to org.springframework.ui.velocity.VelocityEngineFactoryBean

这是我写的Java配置文件。我在 SimpleRegistrationService 方法的 velocityEngine 中发现了以下错误。

setVelocity engine(org.apache.velocity.app.VelocityEngine)in SimpleRegistrationService cannot be applied to org.springframework.ui.velocity.VelocityEngineFactoryBean

在 "resource.loader=class" 附近,我遇到了这个错误

 setVelocityProperties(java.util.Properties) in VelocityEngineFactory cannot be applied to (java.lang.String, java.lang.String)
 
 <interface declaration>, <parcelable declaration>, AidlTokenType.import or AidlTokenType.package expected, got 'resource

请帮忙解决错误。

package com.vlclabs.adsops.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import com.vlclabs.adsops.service.SimpleRegistrationService;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.ui.velocity.VelocityEngineFactoryBean;

@Configuration
public class EmailConfiguration {

    @Bean
    public JavaMailSenderImpl mailSender() {
        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
        mailSender.setHost("mail.csonth.gov.uk");
        return mailSender;
    }

    @Bean
    public SimpleRegistrationService registrationService(JavaMailSenderImpl mailSender, VelocityEngineFactoryBean velocityEngine) {
        SimpleRegistrationService registrationService = new SimpleRegistrationService();
        registrationService.setMailSender(mailSender);
        registrationService.setVelocityEngine(velocityEngine);
        return registrationService;
    }

    @Bean
    public VelocityEngineFactoryBean velocityEngine() {
        VelocityEngineFactoryBean velocityEngine = new VelocityEngineFactoryBean();
        velocityEngine.setVelocityProperties("resource.loader=class", "class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
        return velocityEngine;
    }
}

看起来你在滥用 velocityProperties,它应该是这样的:

@Bean
public VelocityEngineFactoryBean velocityEngine() {
    VelocityEngineFactoryBean velocityEngine = new VelocityEngineFactoryBean();

    Properties velocityProperties = new Properties();
    velocityProperties.put("resource.loader", "class");
    velocityProperties.put("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
    velocityEngine.setVelocityProperties(velocityProperties);

    return velocityEngine;
}

因为你的 velocityEngine 是一个 Spring FactoryBean,而不是你想使用的具体 VelocityEngine,你要么需要调用 factoryBean 的 getObject() 方法,要么注入VelocityEngine 本身,所以 Spring 会为你调用 getObject()

@Bean
public SimpleRegistrationService registrationService(JavaMailSenderImpl mailSender, VelocityEngineFactoryBean velocityEngine) {
    SimpleRegistrationService registrationService = new SimpleRegistrationService();
    registrationService.setMailSender(mailSender);
    registrationService.setVelocityEngine(velocityEngine.getObject()); // <--- getObject
    return registrationService;
}

// VelocityEngine as parameter type, not VelocityEngineFactoryBean
@Bean
public SimpleRegistrationService registrationService(JavaMailSenderImpl mailSender, VelocityEngine velocityEngine) { 
    SimpleRegistrationService registrationService = new SimpleRegistrationService();
    registrationService.setMailSender(mailSender);
    registrationService.setVelocityEngine(velocityEngine); // <-- no getObject() needed
    return registrationService;
}

有关 FactoryBeans 的详细信息,请参阅杰出的 Josh Long 的这篇博文:https://spring.io/blog/2011/08/09/what-s-a-factorybean