Example of Custom Scope in Spring
April 16, 2013
In spring there are scopes like singleton, prototype etc. According to the requirement, spring allows to create custom scope. To understand we will create a Thread scope. Thread scope means a bean creation and destruction will be limited to a thread life cycle. We will understand it step by step.
Create Custom Scope Class
Below class is the custom thread scope. Scope is the interface and every custom scope class implements this interface and implements the methods.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 java class 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-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>
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
ConfigurableBeanFactory beanFactory= new DefaultListableBeanFactory(); Scope threadScope= new CustomThreadScope(); beanFactory.registerScope("customThread", threadScope);