Setting up Metadata-driven Autoproxy

Autoproxy

"Automagically" proxy the beans definitions affected by the caching services.

Example:

For more information about autoproxy, please read the Spring's Documentation.

Source-level Metadata Processor

Retrieves the source-level metadata that specifies which methods of the bean definitions should be involved in caching and which ones should be involved in flushing the cache. Currently, Spring supports only Commons-Attributes.

Advisor for Caching

This advisor tells "autoproxy" to create proxies only for the bean definitions containing source-level metadata for caching. It should be an instance of org.wanghy.cache.interceptor.caching.CachingAttributeSourceAdvisor.

Constructor arguments:

  1. An instance of org.wanghy.cache.interceptor.caching.CachingInterceptor.

    Stores in the cache the return values of the intercepted methods. It only intercepts the methods that contain source-level metadata for caching.

    Properties:

    1. cacheProviderFacade (required).

      The facade for the cache implementation to use. It must be an implementation of org.wanghy.cache.provider.CacheProviderFacade.

      For more information about setting up cache providers, click here.

    2. cacheKeyGenerator (optional).

      Generates the keys used to store/retrieve cache entries. It should be an implementation of org.wanghy.cache.key.CacheKeyGenerator. If there is not any CacheKeyGenerator specified, the interceptor will use an instance of org.wanghy.cache.key.HashCodeCacheKeyGenerator.

    3. cachingAttributeSource (required).

      Retrieves source-level metadata for caching from the bean definitions. It should be an instance of org.wanghy.cache.interceptor.caching.MetadataCachingAttributeSource.

      Properties:

      1. attributes (required).

        Implementation of the source-level metadata processor to use.

    4. entryStoredListener (optional).

      Listener that is notified each time an entry is added to the cache. It should be an implementation of org.wanghy.cache.interceptor.caching.EntryStoredListener. There are not any implementations of this interface.

Example:

<bean id="cachingAttributeSource"
    class="org.wanghy.cache.interceptor.caching.MetadataCachingAttributeSource">
    <property name="attributes">
        <ref local="attributes" />
    </property>
</bean>

<bean id="cachingInterceptor"
    class="org.wanghy.cache.interceptor.caching.CachingInterceptor">
    <property name="cacheProviderFacade">
        <ref local="cacheProvider" />
    </property>
    <property name="cachingAttributeSource">
        <ref local="cachingAttributeSource" />
    </property>
</bean>

<bean id="cachingAttributeSourceAdvisor"
    class="org.wanghy.cache.interceptor.caching.CachingAttributeSourceAdvisor">
    <constructor-arg>
        <ref local="cachingInterceptor" />
    </constructor-arg>
</bean>

Advisor for Flushing the Cache

This advisor tells "autoproxy" to create proxies only for the bean definitions containing source-level metadata for flushing the cache. It should be an instance of org.wanghy.cache.interceptor.flush.CacheFlushAttributeSourceAdvisor.

Constructor arguments:

  1. An instance of org.wanghy.cache.interceptor.flush.CacheFlushInterceptor.

    Flushes the cache or parts of the cache before or after executing the intercepted methods. It only intercepts the methods that contain source-level metadata for flushing the cache.

    Properties:

    1. cacheProviderFacade (required).

      The facade for the cache implementation to use. It must be an implementation of org.wanghy.cache.provider.CacheProviderFacade.

      For more information about setting up cache providers, click here.

    2. cacheFlushAttributeSource (required).

      Retrieves source-level metadata for flushing the cache from the bean definitions. It should be an instance of org.wanghy.cache.interceptor.flush.MetadataCacheFlushAttributeSource.

      Properties:

      1. attributes (required).

        Implementation of the source-level metadata processor to use.

Example:

<bean id="cacheFlushAttributeSource"
    class="org.wanghy.cache.interceptor.flush.MetadataCacheFlushAttributeSource">
    <property name="attributes">
        <ref local="attributes" />
    </property>
</bean>

<bean id="cacheFlushInterceptor"
    class="org.wanghy.cache.interceptor.flush.CacheFlushInterceptor">
    <property name="cacheProviderFacade">
        <ref local="cacheProvider" />
    </property>
    <property name="cacheFlushAttributeSource">
        <ref local="cacheFlushAttributeSource" />
    </property>
</bean>

<bean id="cacheFlushAttributeSourceAdvisor"
    class="org.wanghy.cache.interceptor.flush.CacheFlushAttributeSourceAdvisor">
    <constructor-arg>
        <ref local="cacheFlushInterceptor" />
    </constructor-arg>
</bean>

Definition of the Beans to Advise

We need to define the beans we want to be advised or proxied, i.e. the bean definitions affected by the caching services. For this example, we will use org.wanghy.cache.integration.CacheableImpl, which is the one used in the integration tests.

<bean id="cacheable"
    class="org.wanghy.cache.integration.CacheableImpl">
    <property name="names">
        <list>
            <value>James Gosling</value>
        </list>
    </property>
</bean>

Source-level Metadata for Caching

We need to add source-level metadata to the methods which return values should be stored in the cache.

The source-level metadata attribute (or annotation) we need for caching is org.wanghy.cache.interceptor.caching.Cached. This annotation is the same for any cache provider.

Properties:

  1. cacheProfileId (required).

    The id of the cache profile to be used to cache the return value of the annotated method. This id should be equal to the key used to store the cache profile in the facade (either inside a java.util.Map or a java.util.Properties.) For more information about cache profiles please read "Setting up the Cache Provider."

This is how we add source-level metadata to a method:

/**
 * @see Cacheable#getName(int)
 * 
 * @@org.wanghy.cache.interceptor.caching.Cached(cacheProfileId="test")
 */
public String getName(int index) {
    return (String) this.names.get(index);
}

Notice that the id of the cache profile to use is highlighted in red. A cache profile with the same id should exist in the cache provider facade:

<bean id="cacheProvider"
    class="...">
    <property name="cacheManager">
        <ref local="cacheManager"/>
    </property>

    <!-- Cache profiles specified as a java.util.Map -->
    <property name="cacheProfiles">
        <map>
            <entry key="test">
                <!-- Profiles ommited.  They depend on the implementation of the Cache Provider. -->
            </entry>
        </map>
    </property>

    <!-- Cache profiles specified as a java.util.Properties -->
    <property name="cacheProfiles">
        <props>
            <prop key="test">...</prop>
        </props>
    </property>
</bean>

Source-level Metadata for Flushing the Cache

We need to add source-level metadata to the methods that when executed, flush the cache.

The source-level metadata attribute (or annotation) we need for flushing the cache is org.wanghy.cache.interceptor.flush.FlushCache. This annotation is the same for any cache provider.

Properties:

  1. cacheProfileIds (required).

    The ids of the cache profiles to be used to flush the cache. This ids should be equal to the keys used to store the cache profiles in the facade (either inside a java.util.Map or a java.util.Properties.) For more information about cache profiles please read "Setting up the Cache Provider."

  2. flushedBeforeExecution (optional).

    Flag that indicates if the cache should be flushed before or after the execution of the annotated method.

This is how we add source-level metadata to a method:

/**
 * @see Cacheable#getName(int)
 * 
 * @@org.wanghy.cache.interceptor.flush.FlushCache(cacheProfileIds="test,main")
 */
public void updateName(int index, String name) {
    thisnames.set(index, name);
}

Notice that the ids of the cache profiles to use are highlighted in red and blue. Cache profiles with the same ids should exist in the cache provider facade:

<bean id="cacheProvider"
    class="...">
    <property name="cacheManager">
        <ref local="cacheManager"/>
    </property>

    <!-- Cache profiles specified as a java.util.Map -->
    <property name="cacheProfiles">
        <map>
            <entry key="test">
                <!-- Profiles ommited.  They depend on the implementation of the Cache Provider. -->
            </entry>
            <entry key="main">
                <!-- Profiles ommited.  They depend on the implementation of the Cache Provider. -->
            </entry>
        </map>
    </property>

    <!-- Cache profiles specified as a java.util.Properties -->
    <property name="cacheProfiles">
        <props>
            <prop key="test">...</prop>
            <prop key="main">...</prop>
        </props>
    </property>
</bean>