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)