带有 AOP 的 Spring 会话范围 bean 中的问题

Posted

技术标签:

【中文标题】带有 AOP 的 Spring 会话范围 bean 中的问题【英文标题】:problem in Spring session scope bean with AOP 【发布时间】:2010-12-29 09:43:49 【问题描述】:

我想在 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】:

使用 scoped-proxies,Spring 在上下文初始化时仍然需要知道 bean 的类型,而在这种情况下它没有这样做。您需要尝试提供更多信息。

我注意到您在currentUser 的定义中只指定了factory-bean,没有指定factory-method。实际上,我很惊讶这是一个有效的定义,因为这两者通常一起使用。所以尝试将factory-method 属性添加到currentUser,它指定userProviderFactoryBean 上创建用户bean 的方法。该方法需要有一个 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 属性在工厂不是 FactoryBean 实现而只是 POJO 时使用,它允许您明确告诉 Spring 如何使用工厂。但是因为你使用的是FactoryBean,所以不需要这个属性。

【讨论】:

UserProvider 类实现了 Spring 的 FactoryBean 接口。所以它已经实现了方法 public Object getObject();公共类 getObjectType();公共布尔 isSingleton();。所以这就是为什么我没有指定工厂方法 啊,愚蠢的错误..但感谢您让我明白。 :)

以上是关于带有 AOP 的 Spring 会话范围 bean 中的问题的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot,Spring Security,会话范围 Bean 的会话超时问题,@PreDestroy

如何设置 Spring 会话范围 bean 的属性名称?

是否可以使用会话中的属性配置 Spring 会话范围的 bean?

Spring 3 MVC:在 MVC 控制器方法参数中公开会话范围的 bean

Spring在AuthenticationSuccessHandler中自动装配会话范围bean不起作用

就序列化而言,Spring 会话范围的 bean(控制器)和对服务的引用