当范围是可选的时,使用scoped bean?

时间:2014-04-07 15:52:30

标签: java spring configuration scope

当我需要一些bean时,我有一个范围有时不存在。这本身并不是问题;我可以在这些情况下使用默认值。我的问题是自动装配。场景大致如下:

  1. 我有一个范围内的bean ICurrentLocale。它的范围是User,范围取决于用户当前是否已登录。
  2. Autowire bean foo包含字段@Autowired ICurrentLocale currentLocale;
  3. foo上调用一些方法。
  4. 用户登录。现在,我有一个范围User
  5. foo上调用一些方法。
  6. 我的问题是,在第5点,自动装配的ICurrentLocale bean仍然是相同的,尽管在用户的范围内创建了一个新的bean。

    是否有一个好的/简单/可理解的方法来构建一个弹簧配置,当在同一个线程中输入新范围时,该配置会自动重新连接bean?

    或许我可以问春天"刷新"代理?

    编辑以下是我目前的范围实施:

    @Override
    public Object get( String name, final ObjectFactory<?> objectFactory ) {
        CurrentUserSession currentSession = userSessionFactory.getCurrentSession();
        if( currentSession == null ) {
            if( isLocaleProvider( name ) ) {
                return createLocaleProvider();
            }
            throw new BeanCreationException( "Could not create bean " + name + " the bean scope " + NAME + " can be used only after the user has signed in" );
        }
    
        Object bean = currentSession.getBean(name, objectFactory);
        return bean;
    }
    

    正如您所看到的,只要没有用户登录,我就创建了一个虚拟bean。如果我有一个会话,我会查看会话中的缓存。如果bean还不存在,我会使用objectFactory创建一个新的。

2 个答案:

答案 0 :(得分:0)

也许我误解了你的问题。

你的ICurrentLocale bean应该是

@Component
@Scope(value = "user", proxy-mode = "ScopedProxyMode.TARGET_CLASS")
public class CurrentLocaleImpl implements ICurrentLocale {
   ...
}

或相应的@Bean或XML配置。

通过这样的配置,Spring将为您的注入目标创建一个代理。换句话说,在

@Autowired
private ICurrentLocale currentLocale;

您将没有CurrentLocaleImpl对象,您将拥有一个代理对象,该对象具有对基础BeanFactory的引用。

  

5.在foo上调用一些方法。

     

我的问题是,在第5点,自动连接的ICurrentLocale bean是   尽管新的豆子已经创造了,但仍然是相同的   用户的范围。

当您在代理bean上调用方法时,代理将尝试使用您的CurrentLocaleImpl实现从BeanFactory检索实际的Scope对象,然后将方法调用委托给宾语。实际上,您将使用正确的对象,默认对象或抛出异常。

答案 1 :(得分:0)

对于有类似问题的其他人:确保userSessionFactory.getCurrentSession()返回您的期望。

在我的例子中,用户会话附加到当前线程(使用ThreadLocal)。现在一个帮助框架在一个新的后台线程中执行了我的一些代码 - &gt; ThreadLocal返回null,尽管我知道用户已登录。