使用AOP的Spring会话范围bean中的问题

时间:2009-12-23 07:48:02

标签: java spring spring-mvc

我想在HomeController类中注入currentUser实例。所以对于每个请求,HomeController都会有currentUser对象。

我的配置:

<bean id="homeController" class="com.xxxxx.actions.HomeController">
    <property name="serviceExecutor" ref="serviceExecutorApi"/>
    <property name="currentUser" ref="currentUser"/>
</bean>

<bean id="userProviderFactoryBean" class="com.xxxxx.UserProvider">
    <property name="userDao" ref="userDao"/>
</bean>

<bean id="currentUser" factory-bean="userProviderFactoryBean" scope="session">
    <aop:scoped-proxy/>
</bean>

但我收到了以下错误。

Caused by: java.lang.IllegalStateException: Cannot create scoped proxy for bean 'scopedTarget.currentUser': Target type could not be determined at the time of proxy creation.
        at org.springframework.aop.scope.ScopedProxyFactoryBean.setBeanFactory(ScopedProxyFactoryBean.java:94)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1350)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:540)

有什么问题?还有更好/更简单的选择吗?

干杯。

1 个答案:

答案 0 :(得分:4)

使用作用域代理,Spring在初始化上下文时仍然需要知道bean的类型,在这种情况下,它无法这样做。您需要尝试提供更多信息。

我注意到您只在factory-bean的定义中指定了currentUser,未指定factory-method。我实际上很惊讶这是一个有效的定义,因为这两个通常是一起使用的。因此,请尝试将factory-method属性添加到currentUser,它指定创建用户bean的userProviderFactoryBean上的方法。该方法需要具有User类的返回类型,Spring将使用该类来推断currentUser的类型。


编辑:好的,在您的评论如下之后,您似乎误解了如何在Spring中使用工厂bean。当您拥有FactoryBean类型的bean时,您也不需要使用factory-bean属性。所以不要这样:

<bean id="userProviderFactoryBean" class="com.xxxxx.UserProvider">
    <property name="userDao" ref="userDao"/>
</bean>

<bean id="currentUser" factory-bean="userProviderFactoryBean" scope="session">
    <aop:scoped-proxy/>
</bean>

你只需要这个:

<bean id="currentUser" class="com.xxxxx.UserProvider" scope="session">
    <aop:scoped-proxy/>
    <property name="userDao" ref="userDao"/>
</bean>

这里,UserProviderFactoryBean,Spring知道如何处理它。最终结果是currentUser bean将是UserProvider生成的任何内容,而不是UserProvider本身的实例。

当工厂不是factory-bean实现,而只是POJO时,使用FactoryBean属性,它允许您明确告诉Spring如何使用工厂。但是因为您使用FactoryBean,所以不需要此属性。