3

我有一个用户类:

@Component
@Scope("session")
public class User {
    private String username;
}

和一个控制器类:

@Controller
public class UserManager {
    @Autowired
    private User user;

    @ModelAttribute("user")
    private User createUser() {
        return user;
    }

    @RequestMapping(value = "/user")
    public String getUser(HttpServletRequest request) {
        Random r = new Random();
        user.setUsername(new Double(r.nextDouble()).toString());
        request.getSession().invalidate();
        request.getSession(true);
        return "user";
    }
}

我使会话无效,以便下次我到达 /users 时,我得到另一个用户。由于用户的会话范围,我期待一个不同的用户,但我得到的是同一个用户。我在调试模式下检查,它在内存中是相同的对象 id。我的 bean 是这样声明的:

    <bean id="user" class="org.synchronica.domain.User">
        <aop:scoped-proxy/>
    </bean>

我是春天的新手,所以我显然做错了什么。我希望每个会话都有一个 User 实例。如何?

4

1 回答 1

3

这是预期的行为。当您使用代理标记 bean 时,<aop:scoped-proxy/>会为它创建一个代理。如果有 bean 的接口,则创建 java 动态代理,否则创建基于 CGLIB 的代理 - 在您的情况下,由于您的 User 类没有父类/接口,将为您创建基于 CGLIB 的代理。

现在要注意的是,这个代理将被注入到你的所有类中,这就是为什么你只看到 1 个实例(本质上是代理的),代理知道如何管理范围 - 只要你去通过你的类的方法,所以在你的情况下,如果你通过 getter 和 setter 调用来获取你的 User 类的属性,你应该看到适合反映会话的值。

于 2012-11-23T17:01:34.390 回答