View Javadoc
1   package pl.matsuo.core.web.scope;
2   
3   import org.slf4j.Logger;
4   import org.slf4j.LoggerFactory;
5   import org.springframework.beans.factory.ObjectFactory;
6   import org.springframework.beans.factory.config.Scope;
7   import org.springframework.core.NamedThreadLocal;
8   import org.springframework.web.context.request.AbstractRequestAttributesScope;
9   import org.springframework.web.context.request.RequestAttributes;
10  import org.springframework.web.context.request.RequestContextHolder;
11  
12  import java.util.HashMap;
13  import java.util.Map;
14  
15  /**
16   * Session scope modification that provides bean even outside of http request processing.
17   *
18   * Created by marek on 19.07.14.
19   */
20  public class WideSessionScope extends AbstractRequestAttributesScope implements Scope {
21    private static final Logger logger = LoggerFactory.getLogger(WideSessionScope.class);
22  
23  
24    protected Map<String, ThreadLocal<Object>> objectHolders = new HashMap<>();
25  
26  
27    @Override
28    protected int getScope() {
29      // constant higher than values from RequestAttributes.
30      return 13;
31    }
32  
33  
34    @Override
35    public String getConversationId() {
36      try {
37        return RequestContextHolder.currentRequestAttributes().getSessionId();
38      } catch (IllegalStateException e) {
39        logger.debug("outside web session");
40        e.printStackTrace();
41        return "non_web_";
42      }
43    }
44  
45  
46    @Override
47    public Object get(String name, ObjectFactory<?> objectFactory) {
48      try {
49        Object mutex = RequestContextHolder.currentRequestAttributes().getSessionMutex();
50        synchronized (mutex) {
51          return super.get(name, objectFactory);
52        }
53      } catch (IllegalStateException e) {
54        logger.debug("outside web session");
55        ThreadLocal<Object> objectHolder = objectHolders.get(name);
56        if (objectHolder == null) {
57          objectHolders.put(name, new NamedThreadLocal<>("wideScopeObjectHolder_" + name));
58          objectHolder = objectHolders.get(name);
59        }
60  
61        if (objectHolder.get() == null) {
62          objectHolder.set(objectFactory.getObject());
63        }
64        return objectHolder.get();
65      }
66    }
67  
68  
69    @Override
70    public Object remove(String name) {
71      try {
72        Object mutex = RequestContextHolder.currentRequestAttributes().getSessionMutex();
73        synchronized (mutex) {
74          return super.remove(name);
75        }
76      } catch (IllegalStateException e) {
77        logger.debug("outside web session");
78        Object object = objectHolders.get(name).get();
79        objectHolders.get(name).set(null);
80        return object;
81      }
82    }
83  
84  
85    @Override
86    public void registerDestructionCallback(String name, Runnable callback) {
87      try {
88        logger.debug("outside web session");
89        RequestAttributes attributes = RequestContextHolder.currentRequestAttributes();
90        attributes.registerDestructionCallback(name, callback, getScope());
91      } catch (IllegalStateException e) {
92  
93      }
94    }
95  }
96