JavaBlog.fr / Java.lu DEVELOPMENT,Java,Spring Java/Spring: Data caching – Intercept method calls and put their returns in server-side cache with AOP/MBEAN/JCONSOLE

Java/Spring: Data caching – Intercept method calls and put their returns in server-side cache with AOP/MBEAN/JCONSOLE

Hi,

In a previous article Java/Spring: Measure performance and time processing with AOP on server side, I have presented a solution in order to measure performance and time processing on server side via an AOP layer (AOPALLIANCE library in Spring framework) to measure the execution time of the methods in the persistence layer HIBERNATE.

So in this article, I propose you to use an other AOP layer (AOPALLIANCE library in Spring framework) in order to caching data on server-side by intercept method calls and put their returns in a cache. Then, I will expose several solutions to invalidate the data cached: AOP layer, MBEAN/JCONSOLE, servlet/web service. This solution is more useful for data which don’t be modified frequently.

I. Technologies
To avoid the systematic calls to the persistence layer for data which change rarely, we will develop a system data cache on server-side with AOP layer to intercept and put in cache the calls to methods defined in the given beans.

To illustrate our previous explanations, we will create a Web project with:

  • a Spring context defined in a XML file spring-cacheinterceptor-config.xml,
  • a servlet context listener named SpringContextLoader to load this Spring context,
  • a singleton named ApplicationContextContainer which will give an access to the Spring context (see my post on this topic Access to Spring context in all places or layers of an application),
  • a mock service from persistence layer with the classes ServiceToCache,
  • an AOP layer with a probe named CacheInterceptor,
  • a simple test class named CacheInterceptorTest,
  • the JARs cglib-2.0.2.jar, commons-lang-2.0.jar, commons-logging-1.0.4.jar, commons-logging-1.1.1.jar, commons-pool-1.1.jar, commons-validator.jar (version 1.0.2), jnp-client.jar (version 4.2.3.GA), jstl.jar (version 1.1.2), mail.jar (version 1.3), spring-2.5.6.jar, spring-2.5.6.SR03.jar, spring-mock-1.2.7.jar, spring-webmvc-2.5.6.jar, spring-webmvc-2.5.6.SR03.jar and standard.jar (version 1.1.2).

II. Spring context
The Spring context is defined in a XML file spring-cacheinterceptor-config.xml:

01<?xml version="1.0" encoding="UTF-8"?>
02 
03<!DOCTYPE beans PUBLIC
04    "-//SPRING//DTD BEAN//EN"
06     
07<beans
08    default-autowire="no"
09    default-lazy-init="false"
10    default-dependency-check="none">
11 
12<!--
13 | BEAN METIER
14 -->
15    <bean name="serviceToCache" class="com.ho.test.aop.cache.service.ServiceToCache" />
16 
17<!--
18 | MISE EN CACHE: mettre en cache le résultat des méthodes "methode1ToCache" et "method3" du bean ServiceToCache.
19 -->
20    <bean name="cacheInterceptor" class="com.ho.test.aop.cache.service.common.CacheInterceptor" singleton="true" >
21        <property name="cacheTimeInSeconds" value="86400"/>
22        <property name="methodsToCache">
23            <list>
24                <value>method1ToCache</value>
25                <value>method3</value>
26            </list>
27        </property>
28    </bean>
29     
30     <bean name="module.logger.Proxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
31        <property name="beanNames">
32            <list>
33                <value>serviceToCache</value>
34            </list>
35        </property>
36        <property name="interceptorNames">
37            <list>
38                <value>cacheInterceptor</value>
39            </list>
40        </property>
41     </bean>
42  
43<!--  ... -->
44 
45</beans>

… more, we declare a servlet context listener named SpringContextLoader to load this Spring context in the web deployment descriptor web.xml:

01<?xml version="1.0" encoding="UTF-8"?>
02<web-app ...>
03...
04<listener>
05    <listener-class>com.ho.test.aop.cache.spring.utils.SpringContextLoader</listener-class>
06</listener>
07<context-param>
08    <param-name>CONFIG_SPRING_FILE</param-name>
09    <param-value>/WEB-INF/spring-cacheinterceptor-config.xml</param-value>
10</context-param>
11</web-app>

The code of servlet context listener SpringContextLoader:

01public class SpringContextLoader implements ServletContextListener {
02    /**
03     * Method contextDestroyed
04     * @param arg0
05     * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
06     */
07    public void contextDestroyed(ServletContextEvent arg0) { }
08 
09    /**
10     * Method contextInitialized
11     * @param arg0
12     * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
13     */
14    public void contextInitialized(ServletContextEvent ctx) {
15        String springFileName = ctx.getServletContext().getInitParameter("CONFIG_SPRING_FILE");
16        ApplicationContextContainer.getInstance(springFileName, ctx.getServletContext());
17    }
18}

… and singleton ApplicationContextContainer:

01public class ApplicationContextContainer {
02 
03    private static Log log = LogFactory.getLog(ApplicationContextContainer.class);
04 
05    private final static String SPRING_BUSINESS_CONFIG_XML = "/WEB-INF/spring-cacheinterceptor-config.xml";
06     
07    /**
08     * Instance
09     */
10    private static ApplicationContextContainer instance = null;
11     
12    /**
13     * Contains the spring configuration.
14     */
15    private XmlWebApplicationContext ctx = null;
16 
17    private ApplicationContextContainer() {}
18     
19    /**
20     * Getinstance method.
21     */
22    public static synchronized ApplicationContextContainer getInstance() {
23        return getInstance(SPRING_BUSINESS_CONFIG_XML, null);
24    }
25    public static synchronized ApplicationContextContainer getInstance(String springContextFile, ServletContext servletContext) {
26        if (null == instance) {
27            instance = new ApplicationContextContainer();
28            instance.ctx = new XmlWebApplicationContext(); 
29            instance.ctx.setConfigLocation(springContextFile);
30            instance.ctx.setServletContext(servletContext);
31            instance.ctx.refresh();
32        } // end-if
33        return instance;
34    }
35     
36    /**
37     * Retrieve the spring bean corresponding to the given key.
38     * @param key
39     * @return
40     */
41    public static Object getBean(String key) {
42        return getInstance().ctx.getBean(key);
43    }
44     
45    public XmlWebApplicationContext getContext() {
46        return ctx;
47    }
48}

III. Beans to “cache”
ServiceToCache: The calls to the methods method1ToCache and method3 of this class will be monitored by AOP in order to put in cache their returns. But its methods method2, save, delete, update and saveOrUpdate.

01public class ServiceToCache implements IServiceToCache {
02    // -------------------------------------------------------------- CONSTANTS
03    private static int numero = 0;
04    // --------------------------------------------------------- PUBLIC METHODS
05 
06    /**
07     * This method should wait 2 seconds and return the result.
08     */
09    public String method1ToCache() {
10        pWait(2000);
11        String output = "result..." + (new UID()).toString();
12        return output;
13    }
14 
15    public String method1ToCache(String valeur) {
16        System.out.println("exécution de method1ToCache, valeur = " + valeur);
17        return valeur + numero++ + ".txt";
18    }
19 
20    public String method2() {
21        return "test..." + (new UID()).toString();
22    }
23 
24    public String method3() {
25        String output = "result3...." + (new UID()).toString();
26        return output;
27    }
28 
29    // ---------- METHODS CACHE cleaner
30    public String save() {
31        String output = "save...." + (new UID()).toString();
32        return output;
33    }
34     
35    public String delete() {
36        String output = "delete...." + (new UID()).toString();
37        return output;
38    }
39     
40    public String update() {
41        String output = "update...." + (new UID()).toString();
42        return output;
43    }
44     
45    public String saveOrUpdate() {
46        String output = "saveOrUpdate...." + (new UID()).toString();
47        return output;
48    }
49     
50     
51    // -------------------------------------------------------- PRIVATE METHODS
52    private void pWait(long time) {
53        long begin = Calendar.getInstance().getTimeInMillis();
54        while ((Calendar.getInstance().getTimeInMillis() - begin) < time)
55            ;
56    }
57}

IV. AOP Alliance
The class CacheInterceptor is a probe used to intercept the calls to the certain methods of the bean ServiceToCache defined in the Spring Context via the bean module.logger.Proxy which is type of org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator. As you could see in the below code, the probe:

  • generates the MethodKey of intercepted method with getMethodKey(…),
  • tries to retrieve the cache output from the cache:
    If the output is already present in the cache
    -> return it,
    Else
    -> executes the intercepted method/business and compute the output, store it in the cache and return it.

So, the class named Cache will contain the cached items and several methods to put/retrieve/remove/update an item in the cache and clean the cache.

01public class Cache <KeyType, ElementType> implements ICache<KeyType, ElementType> {
02     
03    /**
04     * Contains the cached items.
05     */
06    private Hashtable<KeyType, Pair<ElementType, Long>> cache = new Hashtable<KeyType, Pair<ElementType, Long>>();
07 
08    /**
09     * Put an item in the cache.
10     */
11    public void put(KeyType key, ElementType value) {
12        Pair<ElementType, Long> p = new Pair(value, Calendar.getInstance().getTimeInMillis()/1000);
13        cache.put(key, p);
14    }
15     
16    /**
17     * Retrieve an item from the Cache.
18     * @param key
19     */
20    public ElementType get(KeyType key, long cacheTimeInSeconds) {
21        Pair<ElementType, Long> p = cache.get(key);
22 
23        if (null == p) {
24            return null;
25        } // end-if
26         
27        if (isRefreshNeeded(p, cacheTimeInSeconds)) {
28            remove(key);
29            return null;
30        } // end-if
31         
32        return p.getFirst();
33    }
34     
35    /**
36     * Update an item in the cache.
37     */
38    public void update(KeyType key, ElementType value) {
39        Pair<ElementType, Long> p = new Pair(value, Calendar.getInstance().getTimeInMillis()/1000);
40        cache.put(key, p);
41    }
42     
43    /**
44     * Clear the cache.
45     */
46    public void clear() { cache.clear(); }
47 
48    /**
49     * @return true if a cache refresh is needed for the given element.
50     */
51    public boolean isRefreshNeeded(Pair<ElementType, Long> p, long cacheTimeInSeconds) {
52         
53        // Verify if the item time is not greater than the given cacheTimeInSeconds
54        boolean needRefresh = false;
55        {
56            // Compute the current item age
57            long ageInSeconds = (Calendar.getInstance().getTimeInMillis()/1000) - p.getSecond();
58            if (ageInSeconds>cacheTimeInSeconds) {
59                 needRefresh = true;
60            } // end-if
61        } // end-block
62         
63        return needRefresh;
64 
65    }
66 
67    //...
68}

An other central class will be CacheInterceptor. This component, implementing the MethodInterceptor interface of AOP, looks for the requested method output in the cache and returns it if found. If not found, it execute the requested method, cache the output and returns it.

01public class CacheInterceptor implements ICacheInterceptor {
02    /**
03     * Contains all the methods name to cache.
04     */
05    private List<String> methodsToCache = new ArrayList<String>();
06 
07    /**
08     * Contains all the cached outputs.
09     * <br/>The items stored as Object are stored with a key in the cache corresponding to :
10     * <br/>method name + parameters separated with "_";
11     */
12    private Cache<String, Object> cache = new Cache<String, Object>();
13 
14    /**
15     * Time in seconds that returned object will stay active in the cache.
16     */
17    private long cacheTimeInSeconds = 0;
18 
19    /**
20     * Method invoke
21     * @param arg0
22     * @return
23     * @throws Throwable
24     * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
25     */
26    public Object invoke(MethodInvocation method) throws Throwable {
27 
28        if (-1 != methodsToCache.indexOf(method.getMethod().getName())) {
29 
30            // Computes the cache key
31            String cacheKey = getCacheKey(method);
32 
33            // Try to retrieve the cache output from the cache
34            Object output = null;
35            {
36                output = cache.get(cacheKey, cacheTimeInSeconds);
37            } // end-block
38 
39            // If the output is already present in the cache
40            // return it
41            if (null != output) {
42                return output;
43            } // end-if
44 
45            // Else, compute the output,
46            // store it in the cache
47            // and return it.
48            output = method.proceed();
49 
50            cache.put(cacheKey, output);
51 
52            return output;
53        } else {
54            Object output = null;
55            output = method.proceed();
56            return output;
57 
58        } // end-if
59    }
60 
61    /**
62     * Erase all the items stored in the cache.
63     */
64    public void clear() {
65        cache.clear();
66    }
67 
68    /**
69     * Get the cache key
70     * @return the key used to store the items in the cache.
71     */
72    private String getCacheKey(MethodInvocation method) {
73        StringBuffer cacheNameBuffer = new StringBuffer();
74        cacheNameBuffer.append(method.getMethod().getDeclaringClass().getName() + "." + method.getMethod().getName() + "(");
75        //cacheNameBuffer.append(method.getMethod().getName());
76 
77        if (method.getArguments() != null && method.getArguments().length > 0) {
78            for (int a = 0; a < method.getArguments().length; a++) {
79                cacheNameBuffer.append("-");
80                if (method.getArguments()[a] == null) {
81                    cacheNameBuffer.append("null");
82                } else {
83                    cacheNameBuffer.append(method.getArguments()[a].toString()
84                            .toLowerCase());
85                } // end-if
86            } // end-for
87        } // end-if
88 
89        return cacheNameBuffer.toString();
90    }
91     
92     
93    //...
94}

V. Tests
The project in attachement contains a test class named CacheInterceptorTest:

001public class CacheInterceptorTest extends TestCase {
002    /**
003     * Contains a reference to the spring context.
004     */
005    private static ApplicationContext ctx = null;
006 
007    public void testCache() {
008         
009        IServiceToCache service = (IServiceToCache) ctx.getBean("serviceToCache");
010        String output1, output2;
011         
012        // Call the method1ToCache, this should take 2 seconds...
013        // verify if the call to the service takes 2 seconds,
014        // if not, fail
015        {
016            Calendar begin = Calendar.getInstance();
017            output1 = service.method1ToCache();
018            System.out.println(output1);
019            Calendar end = Calendar.getInstance();
020            long time = end.getTimeInMillis()-begin.getTimeInMillis();
021            if (time < 2000) {
022                fail("the cache was active...");
023            } // end-if
024             
025        } // end-if
026         
027        // Call the method1ToCache again
028        // verify if the call to the service does NOT take 2 seconds,
029        // if not, fail
030        {
031            Calendar begin = Calendar.getInstance();
032            output2 = service.method1ToCache();
033            System.out.println(output2);
034            Calendar end = Calendar.getInstance();
035            long time = end.getTimeInMillis()-begin.getTimeInMillis();
036            if (time >= 2000) {
037                fail("the cache was NOT active...");
038            } // end-if
039        } // end-if
040         
041        assertTrue(output1.equals(output2));
042    }
043 
044     
045    public void testNoCache() {
046         
047        IServiceToCache service = (IServiceToCache) ctx.getBean("serviceToCache");
048        String output1, output2;
049         
050        // Call the method2, this method id not in cache...
051        // verify if the call to the service takes a different return,
052        // if not, fail
053        {
054            output1 = service.method2();
055            System.out.println(output1);
056        } // end-if
057         
058        // Call the method2 again
059        // verify if the call to the service takes a different return,
060        // if not, fail
061        {
062            output2 = service.method2();
063            System.out.println(output2);
064        } // end-if
065         
066        assertFalse(output1.equals(output2));
067    }
068     
069 
070    public void testCacheClear() {
071        //
072        IServiceToCache service = (IServiceToCache) ctx.getBean("serviceToCache");
073        String output1, output2, output3, output4, output5, output6;
074         
075        // Call the method1ToCache(..), this method id in cache...
076        // verify if the call to the service takes a different return,
077        // if not, fail
078        {
079            output1 = service.method1ToCache("zut");
080            System.out.println("output1 = " + output1);
081            output2 = service.method1ToCache("zut");
082            System.out.println("output2 = " + output2);
083            output3 = service.method1ToCache("zut");
084            System.out.println("output3 = " + output3);
085            //
086            assertTrue(output1.equals(output2));
087            assertTrue(output1.equals(output3));
088        } // end-if
089         
090        // Clear the cache
091        {
092            CacheInterceptor ix = (CacheInterceptor ) ctx.getBean("cacheInterceptor");
093            ix.clear();
094        }
095         
096        // Call the method1ToCache(..), this method id in cache...
097        // verify if the call to the service takes a different return,
098        // if not, fail
099        {
100            output4 = service.method1ToCache("tac");
101            System.out.println("output4 = " + output4);
102            output5 =  service.method1ToCache("zut");
103            System.out.println("output5 = " + output5);
104            output6 =  service.method1ToCache("zut");
105            System.out.println("output6 = " + output6);
106            //
107            assertFalse(output4.equals(output5));
108            assertTrue(output5.equals(output6));
109        }
110    }
111 
112    /**
113     * Method setUp
114     * @throws Exception
115     * @see junit.framework.TestCase#setUp()
116     */
117    @Override
118    protected void setUp() throws Exception {
119        super.setUp();
120 
121        if(this.ctx == null){
122            this.ctx = new FileSystemXmlApplicationContext("C:\\MyFiles\\Development\\Java\\dev\\test_AOP_cache\\WebContent\\WEB-INF\\spring-cacheinterceptor-config.xml");
123        }
124    }
125}

… so, the outputs in console could be like below. For more information, please, analyze the JUNIT CacheInterceptorTest and the bean to cache ServiceToCache .

01result...356e43a2:138bb6a6e49:-8000
02result...356e43a2:138bb6a6e49:-8000
03test...356e43a2:138bb6a6e49:-7fff
04test...356e43a2:138bb6a6e49:-7ffe
05exécution de method1ToCache, valeur = zut
06output1 = zut0.txt
07output2 = zut0.txt
08output3 = zut0.txt
09exécution de method1ToCache, valeur = tac
10output4 = tac1.txt
11exécution de method1ToCache, valeur = zut
12output5 = zut2.txt
13output6 = zut2.txt

VI. Invalidate the cache
Here, I will expose several solutions to invalidate the data cached: AOP layer, MBEAN/JCONSOLE, servlet/web service.
By default, the validity of a data in cache will be 86400 seconds or 24 hours. But, the invalidation of the cache could be automatical or manual:

  • Automatically: the date of validity for cached data is expired, so the CacheInterceptor will be remove the expired data from cache,
  • Automatically: we could implement an other interceptor CacheCleanerInterceptor which will invalidate the data cached when certain methods are called, for example the methods for deleting, modifying or saving. In the project in attachement, there is the interceptor CacheCleanerInterceptor:
    01public class CacheCleanerInterceptor implements ICacheCleanerInterceptor {
    02 
    03    /**
    04     * Contains all the methods name to cache.
    05     */
    06    private List<String> methodsCleaner = new ArrayList<String>();
    07 
    08    /**
    09     * Contains the cache interceptor
    10     */
    11    private ICacheInterceptor cache = null;
    12 
    13    /**
    14     * Method invoke
    15     * @param arg0
    16     * @return
    17     * @throws Throwable
    18     * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
    19     */
    20    public Object invoke(MethodInvocation method) throws Throwable {
    21 
    22        if (-1 != methodsCleaner.indexOf(method.getMethod().getName())) {
    23            // Erase all the items stored in the cache.
    24            cache.clear();
    25        } // end-if
    26         
    27        Object output = method.proceed();
    28        return output;
    29    }
    30 
    31    public List<String> getMethodsCleaner() {
    32        return methodsCleaner;
    33    }
    34 
    35    public void setMethodsCleaner(List<String> methodsCleaner) {
    36        this.methodsCleaner = methodsCleaner;
    37    }
    38 
    39    public ICacheInterceptor getCache() {
    40        return cache;
    41    }
    42 
    43    public void setCache(ICacheInterceptor cache) {
    44        this.cache = cache;
    45    }
    46}

    … This interceptor is defined in the Spring Context file spring-cacheinterceptor-config.xml. In our example, the interceptor CacheCleanerInterceptor will invalidate the cache when the methods save, delete, update and saveOrUpdate of the bean serviceCleaner (com.ho.test.aop.cache.service.ServiceToCache) are called:

    01...
    02<!--
    03 | BEAN METIER
    04 -->
    05    <bean name="serviceCleaner" class="com.ho.test.aop.cache.service.ServiceToCache" />
    06 
    07<!--
    08 | NETTOYAGE DU CACHE: Invalidation automatique
    09 -->
    10    <bean name="cacheCleanerInterceptor" class="com.ho.test.aop.cache.service.common.CacheCleanerInterceptor" singleton="true">
    11        <property name="cache" ref="cacheInterceptor"/>
    12        <property name="methodsCleaner">
    13            <list>
    14                <value>save</value>
    15                <value>delete</value>
    16                <value>update</value>
    17                <value>saveOrUpdate</value>
    18            </list>
    19        </property>
    20    </bean>
    21 
    22    <bean name="module.logger.ProxyCleaner" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
    23        <property name="beanNames">
    24            <list>
    25                <value>serviceCleaner</value>
    26            </list>
    27        </property>
    28        <property name="interceptorNames">
    29            <list>
    30                <value>cacheCleanerInterceptor</value>
    31            </list>
    32        </property>
    33    </bean>
    34...

  • Manually: it will be possible to clear the cache manually via a call to a specific servlet like “AjaxToSpringBeanServlet” which exposes the Spring beans as HTTP service / AJAX. A post Spring: Expose all Spring beans as HTTP/AJAX service has been written about this servlet, so an example to call this servlet in order to clean the cache could be:
    http://localhost:8080/myproject/ajaxToSpringBeanService.do?beanName=cacheInterceptor&beanMethod=clear
  • Manually: an other last solution to clear the cache manually via the use of MBEAN JMX. In the project in attachement, I will expose the CacheInterceptor Spring bean like MBEAN through the component CommonMbeanExporter (org.springframework.jmx.export.MBeanExporter), IRemoteMbeanService and MBeanVo.
    … This interceptor is defined in the Spring Context file spring-cacheinterceptor-config.xml:

    01...
    02<!--
    03 | JMX exposition of the bean cacheInterceptor
    04 -->
    05<bean name="aop.cache.MbeanExporter" class="com.ho.test.mbean.common.CommonMbeanExporter"
    06    lazy-init="false">
    07        <property name="beans">
    08            <map>
    09                <entry   key="cacheInterceptor:application=HUOCACHE,component=HUOCACHECacheInterceptor"
    10                        value-ref="cacheInterceptor" />
    11            </map>
    12        </property>
    13</bean>
    14...

    For more information, I advise you the post Quickly Exposing Spring Beans as JMX MBeans by Cris Holdorph about MBEAN exposing.

    If you encountered error during the start of tomcat, add the last startup parameters of TOMCAT configuration (“VM Arguments” tab):

    -Dcatalina.base=”C:\MyFiles\Development\Java\tools\TomCat” -Dcatalina.home=”C:\MyFiles\Development\Java\tools\TomCat”
    -Dwtp.deploy=”C:\MyFiles\Development\Java\tools\TomCat\webapps”
    -Djava.endorsed.dirs=”C:\MyFiles\Development\Java\tools\TomCat\common\endorsed”
    -Djava.security.auth.login.config=”C:\MyFiles\Development\Java\dev\SpringHibernateIntegration2\README_CONF\jaas.config”
    -Dcom.sun.management.jmxremote.port=”18080″
    -Dcom.sun.management.jmxremote.authenticate=”false”

    …for more information, read http://java.sun.com/j2se/1.5.0/docs/guide/management/agent.html

    …after the deployment of Web application on an AS:

    1INFO: Loading XML bean definitions from file [C:\MyFiles\Development\Java\dev\test_AOP_cache\WebContent\WEB-INF\spring-cacheinterceptor-config.xml]
    2INFO: Pre-instantiating singletons in org.springframework.beans.factory.
    3support.DefaultListableBeanFactory@4cb9e45a: defining beans [serviceToCache,cacheInterceptor,module.logger.Proxy,serviceCleaner,
    4cacheCleanerInterceptor,module.logger.ProxyCleaner,aop.cache.MbeanExporter]; root of factory hierarchy
    5...
    625 juil. 2012 01:51:49 org.springframework.jmx.export.MBeanExporter afterPropertiesSet
    7INFO: Registering beans for JMX exposure on startup
    825 juil. 2012 01:51:49 org.springframework.jmx.export.MBeanExporter registerBeanInstance
    9INFO: Located managed bean 'cacheInterceptor:application=HUOCACHE,component=HUOCACHECacheInterceptor': registering with JMX server as MBean [cacheInterceptor:application=HUOCACHE,component=HUOCACHECacheInterceptor]

    …we can access to defined MBEAN via JConsole . JConsole is a tool for following which is compliance with specification JMX (Java Management Extensions). JConsole uses the instrumentation of the JVM to provide information on performance and resource consumption of applications running on the Java platform. The JConsole executable is in JDK_HOME/bin with JDK_HOME equals to the installation path of JDK (C:\Program Files (x86)\Java\jdk1.6.0_32\bin). If the directory is in the Path environment variable, you can run JConsole by simply typing “JConsole” in the command line. Otherwise, you must type the full path of the executable.

    Finally, there is a class named MbeanTools which is not used in the attachement’s project, however thi class allows the access to MBEAN on a server SERVER1: [SERVER1 (management interface)] –RMI–> [SERVER2 (service of access to MBEANs from a tierce server)] –MbeanTools–> Access to MBEANs on MBEANServer (invoke, get, set, update ..MBEAN).

    So, in JConsole, our mbean is accessible like:

    … click on the button getMethodsToCache:

    …and we can clear the cache by clicking on the button clear:

I don’t have been exhaustive in this article, but, I hope that it will be useful for your needs about data caching on server side. This “home-made” solution is more useful for data which don’t be modified frequently, but, for more complex needs,
there is also other solution of data caching like ECache.

For more informations, you could contact me.

Download: test_AOP_cache.zip

Best regards,

Huseyin OZVEREN

Leave a Reply

Your email address will not be published.

Time limit is exhausted. Please reload CAPTCHA.

Related Post