Domanda

I have a scope which sometimes doesn't exist when I need some bean from it. That in itself isn't a problem; I could use defaults for these cases. My problem is with autowiring. The scenarios goes roughly like this:

  1. I have a scoped bean ICurrentLocale. It's scope is User and the scope depends on whether a user is currently logged in.
  2. Autowire bean foo contains a field @Autowired ICurrentLocale currentLocale;
  3. Call some methods on foo.
  4. A user logs in. Now, I have a scope User
  5. Call some methods on foo.

My problem is that in point #5, the autowired ICurrentLocale bean is still the same despite the fact that a new bean has created in the user's scope.

Is there a good/simple/understandable way to build a spring configuration that automatically rewires beans when a new scope is entered in the same thread?

Or maybe I can ask Spring to "refresh" the proxy?

EDIT Here is my current implementation of the scope:

@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;
}

As you can see, I create a dummy bean as long as no user is logged in. If I have a session, I look into the cache in the session. If the bean doesn't exist, yet, I use the objectFactory to create a new one.

È stato utile?

Soluzione

Maybe I'm misunderstanding your question.

Your ICurrentLocale bean should be something like

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

or the corresponding @Bean or XML configuration.

With such configuration, Spring will create a proxy for your injection target. In other words, in

@Autowired
private ICurrentLocale currentLocale;

you won't have a CurrentLocaleImpl object, you'll have a proxy object that has a reference to the underlying BeanFactory.

5.Call some methods on foo.

My problem is that in point #5, the autowired ICurrentLocale bean is still the same despite the fact that a new bean has created in the user's scope.

When you invoke a method on the proxy bean, the proxy will attempt to retrieve an actual CurrentLocaleImpl object from the BeanFactory using your Scope implementation and then delegate the method call to that object. Effectively, you'll be using either the proper object, the default object, or throwing an exception.

Altri suggerimenti

For other people with similar problems: Make sure userSessionFactory.getCurrentSession() returns what you expect.

In my case, the user session is attached to the current thread (using ThreadLocal). Now a helper framework executed some of my code in a new background thread -> ThreadLocal returned null despite me knowing that a user was logged in.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top