יום שישי, 24 במאי 2013

Custom scope in spring

Spring frameworks enabled extending its  objects creation scopes by allowing to add custom scope to the system.
I have found this capacity very use full in enterprise system when I wants to access the same object from application  layers that doesn’t share the same spring context.(Every layer construct its own spring application context and get the same bean.

 Capture12 

In order to make an object instance available to all the system the solution used to store its state in a cache.When the spring frame work is trying to retrieve an object that is declared with the Enterprise scope it try to find if the object exists in the cache if yes it retrieve the object from the cache and return it .If the object doen’t exists in the cache the scope creates the instance store it in the cache and return it .

In order to implement the custom scope we need to implement the org.springframework.beans.factory.config.Scope interface.
The most important method to override is the  get method .
A sample scope implementation :

package javaapplicationbasicspring;
import org.springframework.beans.factory.ObjectFactory;
import java.util.HashMap;

public class myCustomScop implements org.springframework.beans.factory.config.Scope
{
    static HashMap<String , Object> mObjectCache;
   
    public myCustomScop()
    {
        mObjectCache = new HashMap<>();
    }

    @Override
    public Object get(String string, ObjectFactory<?> of) {
        if (mObjectCache.containsKey(string))
        {
            return mObjectCache.get(string);
        }
     
       Object theSingletonObject = of.getObject();
      
       mObjectCache.put(string, theSingletonObject);
      
       return theSingletonObject;
    }

    @Override
    public Object remove(String string) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void registerDestructionCallback(String string, Runnable r) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public Object resolveContextualObject(String string) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public String getConversationId() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}

The of.getObject(); construct and update an object .
The bean definition:

package javaapplicationbasicspring;
public class SimpleAccountService {
 
   private String mString;
   private SimpleAccountService mParent;  

   private String mTestValue = "Nothing";

    public String getTestValue() {
        return mTestValue;
    }

    public void setTestValue(String mTestValue) {
        this.mTestValue = mTestValue;
    }
          
    public SimpleAccountService()
    {
    }
}
The spring context 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"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:lang="http://www.springframework.org/schema/lang"

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
          http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.1.xsd
">
    <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
    <property name="Enterprise">
    <map>
    <entry key="Enterprise">
    <bean class="javaapplicationbasicspring.myCustomScop"/>
    </entry>
    </map>
    </property>
</bean>

    <bean id="accountService" class="javaapplicationbasicspring.SimpleAccountService" scope="Enterprise">
        <property name="Value">
            <value>Hello Zvika</value>
        </property>
    </bean>
</beans>

The test case :
ClassPathXmlApplicationContext appContextParent = new ClassPathXmlApplicationContext(
                new String[] {"resources/ParentSpringXMLConfig.xml"}  );
      
ClassPathXmlApplicationContext appContextParent2 = new ClassPathXmlApplicationContext(
                new String[] {"resources/ParentSpringXMLConfig.xml"}  );

SimpleAccountService theSimpleAccountService =
                (SimpleAccountService)appContextParent2.getBea("accountService");
          
SimpleAccountService theSimpleAccountService2 =
                (SimpleAccountService)appContextParent.getBean("accountService");
   
theSimpleAccountService.setTestValue ("Zvika");
System.out.print ("Hello: " + theSimpleAccountService2.getTestValue());

and the result is :
Hello: Zvika





 







אין תגובות:

הוסף רשומת תגובה