Create Custom Bean Scope in Spring Example

In this article Custom bean scope we will explore how to create custom scope of bean in the spring example. There are two main scopes of bean in spring singleton and prototype but spring allow us to create custom bean scope too through the interface Scope in the spring Example. As of Spring 2.0, we can define custom spring bean scope as well as modify existing spring bean scopes (except singleton and prototype scopes). So let’s see how to create custom spring bean scope with example.

Create Custom Bean Scope Class

Let’s have a look into below class MyThreadScope.java

/**
 * 
 */
package com.doj.app.scope;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;

/**
 * @author Dinesh.Rajput
 *
 */
public class MyThreadScope implements Scope {
 
 private final ThreadLocal<Object> myThreadScope = new ThreadLocal<Object>() {
  protected Map<String, Object> initialValue() {
   System.out.println("initialize ThreadLocal");
   return new HashMap<String, Object>();
  }
 };
  
 @SuppressWarnings("unchecked")
 @Override
 public Object get(String name, ObjectFactory<?> objectFactory) {
  Map<String, Object> scope = (Map<String, Object>) myThreadScope.get();
  System.out.println("getting object from scope.");
  Object object = scope.get(name);
  if(object == null) {
   object = objectFactory.getObject();
   scope.put(name, object);
  }
  return object;
 }

 @Override
 public String getConversationId() {
  return null;
 }

 @Override
 public void registerDestructionCallback(String name, Runnable callback) {

 }

 @Override
 public Object remove(String name) {
  System.out.println("removing object from scope.");
  @SuppressWarnings("unchecked")
  Map<String, Object> scope = (Map<String, Object>) myThreadScope.get();
  return scope.remove(name);
 }

 @Override
 public Object resolveContextualObject(String name) {
  return null;
 }

}

As above class for custom scope MyThreadScope, we have implemented org.springframework.beans.factory.config.Scope interface to create a own custom scope in the spring container. This interface contain five methods. But following two mandatory methods have to override to create custom spring bean scope.

  • get() method – this method return the bean from the given scope.
  • remove() method – this method remove an object from the scope

Register Created Custom Bean Scope

After creating the custom bean scope, we have to register it with the spring container. So there are two way to register it. Either by it programmatic registration or we can do it via using XML based configuration. Let’s have a look into both configuration as below:

Java Based Configuration:

ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Scope scope = new MyThreadScope();
applicationContext.getBeanFactory().registerScope("myThreadScope", scope);

XML Based Configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
 
 <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
  <property name="scopes">
   <map>
               <entry key="myThreadScope">
                   <bean class="com.doj.app.scope.MyThreadScope"/>
               </entry>
           </map>
  </property>
 </bean>
 
 <bean id="myBean" class="com.doj.app.bean.MyBean" scope="myThreadScope"> 
  <property name="name" value="Dinesh"></property>
 </bean>
</beans>

Using the custom scope

In XML

<bean id="myBean" class="com.doj.app.bean.MyBean" scope="myThreadScope"> 
   <property name="name" value="Dinesh"></property>
</bean>

In Java

@Bean
@Scope("myThreadScope")
MyBean myBean(){
   return new MyBean();
}

Test Class for Custom Scope Example

Main.java

/**
 * 
 */
package com.doj.app.test;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.doj.app.bean.MyBean;

/**
 * @author Dinesh.Rajput
 *
 */
public class Main {
 /**
  * @param args
  */
 public static void main(String[] args) {
  ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
  MyBean myBean = applicationContext.getBean(MyBean.class);
  System.out.println(myBean.getName());
  System.out.println("All registered Scopes are : ");
  for(String scope : applicationContext.getBeanFactory().getRegisteredScopeNames()){
   System.out.println(scope);
  }
  applicationContext.close();
 }

}

Output on Console:

Mar 24, 2017 7:52:44 AM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@433c675d: startup date [Fri Mar 24 07:52:44 IST 2017]; root of context hierarchy
Mar 24, 2017 7:52:44 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
initialize ThreadLocal
getting object from scope.
Dinesh
All registered Scopes are :
myThreadScope
Mar 24, 2017 7:52:44 AM org.springframework.context.support.ClassPathXmlApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@433c675d: startup date [Fri Mar 24 07:52:44 IST 2017]; root of context hierarchy

Custom Bean Scope Example with Source Code

Download this example from Github.

 

Spring Related Topics you may like

 

Previous
Next
Dinesh Rajput

Dinesh Rajput is the chief editor of a website Dineshonjava, a technical blog dedicated to the Spring and Java technologies. It has a series of articles related to Java technologies. Dinesh has been a Spring enthusiast since 2008 and is a Pivotal Certified Spring Professional, an author of a book Spring 5 Design Pattern, and a blogger. He has more than 10 years of experience with different aspects of Spring and Java design and development. His core expertise lies in the latest version of Spring Framework, Spring Boot, Spring Security, creating REST APIs, Microservice Architecture, Reactive Pattern, Spring AOP, Design Patterns, Struts, Hibernate, Web Services, Spring Batch, Cassandra, MongoDB, and Web Application Design and Architecture. He is currently working as a technology manager at a leading product and web development company. He worked as a developer and tech lead at the Bennett, Coleman & Co. Ltd and was the first developer in his previous company, Paytm. Dinesh is passionate about the latest Java technologies and loves to write technical blogs related to it. He is a very active member of the Java and Spring community on different forums. When it comes to the Spring Framework and Java, Dinesh tops the list!

Share
Published by
Dinesh Rajput

Recent Posts

Strategy Design Patterns using Lambda

Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…

2 years ago

Decorator Pattern using Lambda

Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…

2 years ago

Delegating pattern using lambda

Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…

2 years ago

Spring Vs Django- Know The Difference Between The Two

Technology has emerged a lot in the last decade, and now we have artificial intelligence;…

2 years ago

TOP 20 MongoDB INTERVIEW QUESTIONS 2022

Managing a database is becoming increasingly complex now due to the vast amount of data…

2 years ago

Scheduler @Scheduled Annotation Spring Boot

Overview In this article, we will explore Spring Scheduler how we could use it by…

2 years ago