Using Custom Scopes, we can define new scope as well as modify the existing scope.
Custom Scope is useful for following scenarios-
- creating a bean scope where beans can be shared between servlet contexts 
- creating a bean scope where beans can be shared within a same thread
We have org.springframework.beans.factory.config.Scope interface in Spring, by implementing that we can create a custom scope in the spring container. This Scope interface contains four methods,
get(..)  get method is used to return the bean from the given scope 
remove(..)  remove method is used to remove an object from the scope 
registerDestructionCallback(..)  This is a callback method and gets invoked when the object in this scope is destroyed 
getConversationId()  This method depends on the scope and implementation. For example session scope it returns the sessionid 
NOTE:From the above four methods get() method is the mandatory operation and others are optional.
CustomThreadScope.java
    package com.concretepage;
    import java.util.HashMap;
    import java.util.Map;
    import org.springframework.beans.factory.ObjectFactory;
    import org.springframework.beans.factory.config.Scope;
    public class CustomThreadScope implements Scope 
    {
            CustomThreadLocal customThreadLocal = new CustomThreadLocal();
            @SuppressWarnings("rawtypes")
           @Override
           public Object get(String str, ObjectFactory objectFactory) 
        {
            System.out.println("getting object from scope.");
            @SuppressWarnings("unchecked")
             Map<String, Object> scope = (Map<String, Object>)                     customThreadLocal.get();
            Object object = scope.get(str);
                    if (object == null) {
                            object = objectFactory.getObject();
                            scope.put(str, object);
                    }
                    return object;
           }
         @Override
            public String getConversationId() 
          {
                    return null;
            }
        @Override
          public void registerDestructionCallback(String arg0, Runnable arg1) 
        {
          }
          @Override
            public Object remove(String str) {
                    Map<String, Object> scope = (Map<String, Object>) customThreadLocal.get();
                    return scope.remove(str);
            }
            @Override
            public Object resolveContextualObject(String arg0) {
                    return null;
            }
        class CustomThreadLocal extends ThreadLocal {
                protected Map<String, Object> initialValue() {
                        System.out.println("initialize ThreadLocal");
                        return new HashMap<String, Object>();
                }
        }
}
Now define the below code in app-context.xml
app-conf.xml
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
     <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
      <property name="scopes">
          <map>
              <entry key="customThread">
                  <bean class="com.concretepage.CustomThreadScope"/>
              </entry>
          </map>
      </property>
    </bean>
    <bean id="testA" class="com.concretepage.A"  scope="customThread" />
</beans>
Now define the below class to run the code:
SpringTest.java
package com.concretepage;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTest {
        public static void main(String[] args) {
                ApplicationContext context = new ClassPathXmlApplicationContext("app-conf.xml");
                context.getBean("testA");
        }
}
Output 
getting object from scope.
initialize ThreadLocal
Bean A is initialized
                       
                    
0 Comment(s)