Spring Custom Scope Example

By Arvind Rai, March 10, 2023
Spring provides Scope interface to create custom scopes. The Scope interface is a strategy interface that allows for extending the standard scopes "singleton" and "prototype" of BeanFactory with custom further scopes, registered for a specific key. The Scope implementations are expected to be thread-safe.
In our example, we will create our custom scope as thread scope. Thread scope means a bean creation and destruction will be limited to a thread life cycle.

Create Custom Scope

Find the custom thread scope implementation class.
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>();
		}
	}
} 

Register Custom Scope

We need to register our custom scope class with Spring container. We can do it in JavaConfig as well as in application 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.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.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 run the application.
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 
Note: We can register bean in JavaConfig also. Look into the below code snippet.
ConfigurableBeanFactory beanFactory=  new DefaultListableBeanFactory();
Scope threadScope= new CustomThreadScope();
beanFactory.registerScope("customThread", threadScope); 

Reference

POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE








©2024 concretepage.com | Privacy Policy | Contact Us