Spring 4:FactoryBean上的MethodInvokingFactoryBean<>例

时间:2015-02-27 03:15:03

标签: java spring spring-mvc

我尝试使用org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean在Spring 4中创建FreeMarker配置,然后自定义生成的freemarker.template.Configuration(以更改算术引擎)。

我使用以下XML配置(简化):

<bean id="freemarkerConfiguration" class="org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean">
  <property name="templateLoaderPaths">...</property>
   ...
</bean>

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject" ref="freemarkerConfiguration" />
    <property name="targetMethod" value="setArithmeticEngine" />
    <property name="arguments" value="#{T(freemarker.core.ArithmeticEngine).CONSERVATIVE_ENGINE}" />
</bean>

它有效,但在应用程序启动期间我收到很多警告:

2015-02-27 13:53:03,321 [localhost-startStop-1] [:] WARN  support.DefaultListableBeanFactory - Bean creation exception on FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.beans.factory.config.MethodInvokingFactoryBean#0' defined in ServletContext resource [/WEB-INF/spring/freemarker.xml]: Cannot resolve reference to bean 'freemarkerConfiguration' while setting bean property 'targetObject'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'freemarkerConfiguration': FactoryBean which is currently in creation returned null from getObject

我的理解是它发生是因为FreeMarkerConfigurationFactoryBean实现了FactoryBean<>接口。因此,这个FactoryBean已经准备好了#34;首先,每当需要访问它创建的实际bean(FactoryBean.getObject())时调用freemarker.template.Configuration

似乎MethodInvokingFactoryBean被调用,而底层bean仍在准备&#34;&#34;按FreeMarkerConfigurationFactoryBean,导致FreeMarkerConfigurationFactoryBean.getObject()返回null,方法调用失败。

我怀疑我收到了很多警告,因为Spring反复尝试调用该方法并失败。在某些时候,工厂生成的bean已经准备就绪,方法调用也可以。

所以:

  • 我的分析是否正确?
  • 为什么会这样?我认为依赖注入系统应检测MethodInvokingFactoryBeanfreemarkerConfiguration之间的依赖关系,并在工厂bean准备就绪后调用方法。我尝试在depends-on="freemarkerConfiguration"上添加MethodInvokingFactoryBean,但它没有帮助。
  • 有没有办法在XML中实现我想要的东西(我现在无法切换到Java @Configuration)。基本上我需要一种从XML调用freemarker.core.Configurable.setArithmeticEngine()的方法。

感谢。

2 个答案:

答案 0 :(得分:3)

阅读完一些规范后,我发现这一点,希望对你有用:

<bean id="freemarkerConfiguration" class="org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean">
    <property name="templateLoaderPath" value="/WEB-INF/freemarker/"/>
    <property name="freemarkerSettings">
        <props>
            <prop key="arithmetic_engine">conservative</prop>
        </props>
    </property>
</bean>

参考:Freemarker Docs

答案 1 :(得分:1)

FactoryBean应该创建一个bean,而不是调用bean上的方法!此外,调用版本的方法将尝试通过调用传递的对象的已配置方法来创建一个bean来创建一个新的bean。

您应该查看的是freemarkerSettings的{​​{1}}属性,并设置属性,包括算术引擎:

FreeMarkerConfigurationFactoryBean