Announcement Announcement Module
Collapse
No announcement yet.
Cache with AOP Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Cache with AOP

    Hi, I would like to cache returned value of bean's methods with an advice. I already wrote my advice and it worked, it is generic, so I can associate it with any class, method of my project to get caching behavior.

    My issue, is that, for some class, I would like to have the method cached at the boostrap, or just after my bean is created by the BeanFactory. I wonder where I can do that properly. All the class cached are of type singleton, so they are fully instantiated at the bootstrap.

    In order to cache the value, I guess I will need to have access to the instance of the class cached, the methods cached, and my advice, so I was thinking that it might be done by extending the ProxyFactoryBean.

    Any advice ?

    Olivier

    Here is my context.xml :

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
    	"http&#58;//www.springframework.org/dtd/spring-beans.dtd">
    <beans>
    
    	<bean id="cacheAOP" class="CacheAOP">
    	</bean>
    
    <bean id="cacheMyManagerAdvice" 
    	   class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
    	    <property name="advice">
    	        <ref local="cacheAOP"/>
    	    </property>
    	    <property name="mappedNames">
    	        <list>				<value>getMyValue1</value>
                    <value>getMyValue2</value>
                    <value>getMyValue3</value>		
    	        </list>
    	    </property>
    	</bean>
    
    	<bean id="MyManager" class="org.springframework.aop.framework.ProxyFactoryBean">
    	    <property name="proxyTargetClass"><value>true</value></property>
    		<property name="target">
    	        <bean class="MyManagerImpl">
    	        </bean>
    	   </property>
    	    <property name="interceptorNames">
    	        <list>
    	            <value>cacheMyManagerAdvice</value>
    	        </list>
    	    </property>
    	</bean>
    </beans>

  • #2
    Olivier,

    I also wrote a MethodCacheInterceptor that caches the result of methods' calls. I use the bean name, method name and arguments values to produce the cache key. MethodCacheInterceptor also relies on Spring integration for EHCache for cache regions management.
    You can find the source code here: Caching the result of methods using Spring and EHCache.
    Now back to your question
    One way to do it is to create a BeanMethodInitialization (implements FactoryBeanAware, InitializingBean). BeanMethodInitialization can use a List / String[] / ... property to hold "beanName.method"(s) that have to be called upon context initialization. It can use internal beanFactory property to get a reference to the beans and java reflection to call the methods. This process can be implemented in the bean's afterPropertiesSet method.
    This way, cache management, method result cache and initialization will be perfectly separated / reusable.
    HTH

    Comment


    • #3
      Re: Cache with AOP

      Take a look at Wanghy Cache for Srping http://wanghy.sourceforge.net/cache/index.html. It already does caching at the method level with integration with various caching frameworks plus cache invalidation, etc.

      Comment


      • #4
        Invoke method on MethodCacheInterceptor is Not getting Called

        Hi,

        I am into a serious problem..Probably wrong with my Configuration.The invoke method on the MethodCacheInterceptor is not getting Called.
        Before explanining this,let me explain my Configuration. I'm using Spring EJB+ Spring JDBC..

        My beans :

        Spring-EJB -- A
        Interface -- I
        Implementation Class -- B

        Both A and B implements I.. and B is hidden behind A..Every method call on the EJB will direct the method call to B.. On certain method calls on the Service we need to cache the data, For that I preferred EhCache and used the same what IRBOUHO has suggested..in his article Spring with EHCache

        So, basing upon this I have fixed my configuration But my MethodCachinginterceptor's invoke method is not getting Called..

        My applicationContext.xml looks like this :

        Code:
        <bean id="redemptionService"
        		class="org.springframework.aop.framework.ProxyFactoryBean">
        		<property name="interceptorNames">
        			<list>
        		      <value>slsbInterceptor</value>
        		      <value>methodCachePointCut</value>			      	     
        		    </list>	
        		</property>	
        		<property name="proxyInterfaces" value="com.ftindia.redemption.interfaces.RedemptionManager">
        		</property>			
        	</bean>
        	
        	<bean id="slsbInterceptor" class="org.springframework.ejb.access.SimpleRemoteSlsbInvokerInterceptor">
        		<property name="jndiEnvironment">
                            <props>
                                <prop key = "java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
                                <prop key = "java.naming.provider.url">t3://localhost:7001</prop>
                                <prop key = "java.naming.factory.url.pkgs">weblogic.jndi.factories:weblogic.corba.j2ee.naming.url</prop>
                             </props>
                        </property>    
        		<property name="jndiName" value="Redemption" />
        	<!-- <property name="homeInterface" value="com.ftindia.redemption.interfaces.RedemptionManager" />	 -->	
        	</bean>
        	
        	<bean id="methodCachePointCut" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" >
        		  <property name="advice">
        		    <ref local="methodCacheInterceptor"/>
        		  </property>
        		  <property name="pattern" value="com.ftindia.redemption.interfaces.impl.RedemptionManagerImpl.getAuthDetails">		   
        		  </property>		
        	</bean>
        	
        	<bean id="methodCacheInterceptor" class="com.ftindia.cache.MethodCacheInterceptor">
        	  <property name="cache">
        	    <ref local="methodCache" />
        	  </property>		
        	</bean>
        	
        	<bean id="methodCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
        		<property name="cacheName" value="droseCache1"></property>
        		<property name="cacheManager" ref="cacheManager"></property>
        	</bean>
        		
        	<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        		<property name="configLocation" value="/WEB-INF/ehcache.xml"></property>
        	</bean>

        Here, the methodCache Interceptor's Constructor and the inherited method afterpropertiesSet are both getting called but the invoke method is not getting Called..What is the Solution for this..Can anyone just go through it and solve my problem..

        Thanks for any help..

        Chandru.

        Comment


        • #5
          Looks like you have not configured the "target" property on the ProxyFactoryBean.

          Check the code in bold below:-

          Code:
          <bean id="redemptionService"
          		class="org.springframework.aop.framework.ProxyFactoryBean">
          		<property name="interceptorNames">
          			<list>
          		      <value>slsbInterceptor</value>
          		      <value>methodCachePointCut</value>			      	     
          		    </list>	
          		</property>	
          		<property name="proxyInterfaces" value="com.ftindia.redemption.interfaces.RedemptionManager">
          		</property>
                          <property name="target">
          			 <ref local="<RedemptionMangerImpl>"/>
          		</property>	
          </bean>
          Last edited by nikhil78; Aug 27th, 2007, 03:28 AM.

          Comment


          • #6
            Specified the Target Name

            Hi Nikhil,

            Thanks, Itz working now. Do we have any standard practice to get partial Data from the large Chunks of Data that is stored in the Cache..

            Cheers,

            Chandru.

            Comment


            • #7
              Originally posted by nikhil78 View Post
              Looks like you have not configured the "target" property on the ProxyFactoryBean.

              Check the code in bold below:-

              Code:
              <bean id="redemptionService"
              		class="org.springframework.aop.framework.ProxyFactoryBean">
              		<property name="interceptorNames">
              			<list>
              		      <value>slsbInterceptor</value>
              		      <value>methodCachePointCut</value>			      	     
              		    </list>	
              		</property>	
              		<property name="proxyInterfaces" value="com.ftindia.redemption.interfaces.RedemptionManager">
              		</property>
                              <property name="target">
              			 <ref local="<RedemptionMangerImpl>"/>
              		</property>	
              </bean>
              I feel this is a Configuration issue..but the Continuation made me to post in this..Please react to this..

              Now I have Configured like this..by setting the target RedemptionManagerImpl..everything is working fine..But If in a scenario where target and proxyInterfaces are not local to this package..I mean when we deploy the war and the Jars differently without packing into the single ear..It is not able to look up the proxyInterfaces or the target ..Do I need to Configure any other way..How to enable the ContextLoading between the war file and the various Jars..

              Thanks for any suggestion..

              Comment

              Working...
              X