Tuesday 25 April 2017

Spring: Define Custom scopes

Embedding custom scope into the spring application is three step process.
a.   Create the custom scope
b.   Register the new custom scope
c.   Use the custom scope

a. Create Custom Scope
To define custom scope, you need to implement org.springframework.beans.factory.config.Scope interface. The Scope interface has four methods to get objects from the scope, remove them from the scope, and allow them to be destroyed.

Method
Description
Object get(String name, ObjectFactory<?> objectFactory)
Return the object with the given name from the underlying scope, creating it if not found in the underlying storage mechanism.
Object remove(String name)
Remove the object with the given name from the underlying scope. Returns null if no object was found; otherwise returns the removed Object.
void registerDestructionCallback(String name, Runnable callback)
Register a callback to be executed on destruction of the specified object in the scope.
String getConversationId()
This identifier is different for each scope. For a session scoped implementation, this identifier can be the session identifier.

CustomScope.java
package com.sample.pojo;

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

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

public class CustomScope implements Scope{
 private Map<String, Object> objectMap = Collections.synchronizedMap(new HashMap<String, Object>());

 @Override
 public Object get(String name, ObjectFactory<?> objectFactory) {
  if (!objectMap.containsKey(name)) {
   objectMap.put(name, objectFactory.getObject());
  }
  return objectMap.get(name);
 }

 @Override
 public Object remove(String name) {
  return objectMap.remove(name);
 }

 @Override
 public void registerDestructionCallback(String name, Runnable callback) {
  // Skipping this implementation for time being
 }

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

 @Override
 public String getConversationId() {
  return "CustomScope";
 }

}


Define a POJO class to experiment with custom scope.

Author.java
package com.sample.pojo;

public class Author {
 private String firstName;
 private String lastName;
 private String dateOfBirth;
 private String country;

 public Author() {
  System.out.println("Constructor called");
 }

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public String getDateOfBirth() {
  return dateOfBirth;
 }

 public void setDateOfBirth(String dateOfBirth) {
  this.dateOfBirth = dateOfBirth;
 }

 public String getCountry() {
  return country;
 }

 public void setCountry(String country) {
  this.country = country;
 }

 @Override
 public String toString() {
  StringBuilder builder = new StringBuilder();
  builder.append("Author [firstName=").append(firstName).append(", lastName=").append(lastName)
    .append(", dateOfBirth=").append(dateOfBirth).append(", country=").append(country).append("]");
  return builder.toString();
 }

}

b. Register the new custom scope
You can register the customScope, by adding the bean of type CustomScope to 'CustomScopeConfigurer'. Following snippet adds the bean customScope to spring IOC container.
 <bean id="customScope" class="com.sample.pojo.CustomScope" />

 <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
  <property name="scopes">
   <map>
    <entry key="myScope">
     <ref bean="customScope" />
    </entry>
   </map>
  </property>
 </bean>


myConfiguration.xml
<?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 id="customScope" class="com.sample.pojo.CustomScope" />

 <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
  <property name="scopes">
   <map>
    <entry key="myScope">
     <ref bean="customScope" />
    </entry>
   </map>
  </property>
 </bean>

 <bean id="osho" class="com.sample.pojo.Author" scope="myScope">
  <property name="firstName" value="Chandra Mohan" />
  <property name="lastName" value="Jain" />
  <property name="dateOfBirth" value="11 December 1931" />
  <property name="country" value="India" />
 </bean>

</beans>

c. use CustomScope in your application


HelloWorld.java
package com.sample.test;

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

import com.sample.pojo.Author;
import com.sample.pojo.CustomScope;

public class HelloWorld {
 public static void main(String args[]) {
  ApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "myConfiguration.xml" });
  CustomScope customScope = context.getBean("customScope", CustomScope.class);

  System.out.println("Getting an object of type Author");
  context.getBean("osho", Author.class);

  System.out.println("Getting an object of type Author");
  context.getBean("osho", Author.class);

  System.out.println("Removing the instance \'osho\' from the customScope");
  customScope.remove("osho");
  
  System.out.println("Getting an object of type Author");
  context.getBean("osho", Author.class);

  ((ClassPathXmlApplicationContext) context).close();
 }
}

Output
Getting an object of type Author
Constructor called
Getting an object of type Author
Removing the instance 'osho' from the customScope
Getting an object of type Author
Constructor called


Previous                                                 Next                                                 Home

No comments:

Post a Comment