paulwong

          SPRING CACHE之ConcurrentMapCacheManager改造

          ConcurrentMapCacheManager可以作為一種緩存方案,但不能設(shè)置過期,最大緩存條目等,需進行改造。
          1. pom.xml中加入依賴包
                    <dependency>
                        <groupId>com.google.guava</groupId>
                        <artifactId>guava</artifactId>
                        <version>18.0</version>
                    </dependency>

          2. 改造CacheManager,MyConcurrentMapCacheManager
            package com.paul.common.cache;
            /*
             * Copyright 2002-2014 the original author or authors.
             *
             * Licensed under the Apache License, Version 2.0 (the "License");
             * you may not use this file except in compliance with the License.
             * You may obtain a copy of the License at
             *
             *      
            http://www.apache.org/licenses/LICENSE-2.0
             *
             * Unless required by applicable law or agreed to in writing, software
             * distributed under the License is distributed on an "AS IS" BASIS,
             * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
             * See the License for the specific language governing permissions and
             * limitations under the License.
             
            */

            import java.util.Collection;
            import java.util.Collections;
            import java.util.Map;
            import java.util.concurrent.ConcurrentHashMap;
            import java.util.concurrent.ConcurrentMap;
            import java.util.concurrent.TimeUnit;

            import org.springframework.cache.Cache;
            import org.springframework.cache.CacheManager;
            import org.springframework.cache.concurrent.ConcurrentMapCache;

            import com.google.common.cache.CacheBuilder;

            /**
             * {
            @link CacheManager} implementation that lazily builds {@link ConcurrentMapCache}
             * instances for each {
            @link #getCache} request. Also supports a 'static' mode where
             * the set of cache names is pre-defined through {
            @link #setCacheNames}, with no
             * dynamic creation of further cache regions at runtime.
             *
             * <p>Note: This is by no means a sophisticated CacheManager; it comes with no
             * cache configuration options. However, it may be useful for testing or simple
             * caching scenarios. For advanced local caching needs, consider
             * {
            @link org.springframework.cache.guava.GuavaCacheManager} or
             * {
            @link org.springframework.cache.ehcache.EhCacheCacheManager}.
             *
             * 
            @author Juergen Hoeller
             * 
            @since 3.1
             * 
            @see ConcurrentMapCache
             
            */
            public class MyConcurrentMapCacheManager implements CacheManager {

                private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>(16);

                private boolean dynamic = true;

                private boolean allowNullValues = true;
                
                private long expireTime = 30;
                
                private long maximumSize = 100;


                /**
                 * Construct a dynamic ConcurrentMapCacheManager,
                 * lazily creating cache instances as they are being requested.
                 
            */
                public MyConcurrentMapCacheManager() {
                }

                /**
                 * Construct a static ConcurrentMapCacheManager,
                 * managing caches for the specified cache names only.
                 
            */
                public MyConcurrentMapCacheManager(long expireTime, long maximumSize) {
                    if(expireTime > 0)
                        this.expireTime = expireTime;
                    if(maximumSize > 0)
                        this.maximumSize = maximumSize;
                }


                /**
                 * Specify the set of cache names for this CacheManager's 'static' mode.
                 * <p>The number of caches and their names will be fixed after a call to this method,
                 * with no creation of further cache regions at runtime.
                 * <p>Calling this with a {
            @code null} collection argument resets the
                 * mode to 'dynamic', allowing for further creation of caches again.
                 
            */
                public void setCacheNames(Collection<String> cacheNames) {
                    if (cacheNames != null) {
                        for (String name : cacheNames) {
                            this.cacheMap.put(name, createConcurrentMapCache(name));
                        }
                        this.dynamic = false;
                    }
                    else {
                        this.dynamic = true;
                    }
                }

                /**
                 * Specify whether to accept and convert {
            @code null} values for all caches
                 * in this cache manager.
                 * <p>Default is "true", despite ConcurrentHashMap itself not supporting {
            @code null}
                 * values. An internal holder object will be used to store user-level {
            @code null}s.
                 * <p>Note: A change of the null-value setting will reset all existing caches,
                 * if any, to reconfigure them with the new null-value requirement.
                 
            */
                public void setAllowNullValues(boolean allowNullValues) {
                    if (allowNullValues != this.allowNullValues) {
                        this.allowNullValues = allowNullValues;
                        // Need to recreate all Cache instances with the new null-value configuration
                        for (Map.Entry<String, Cache> entry : this.cacheMap.entrySet()) {
                            entry.setValue(createConcurrentMapCache(entry.getKey()));
                        }
                    }
                }

                /**
                 * Return whether this cache manager accepts and converts {
            @code null} values
                 * for all of its caches.
                 
            */
                public boolean isAllowNullValues() {
                    return this.allowNullValues;
                }


                @Override
                public Collection<String> getCacheNames() {
                    return Collections.unmodifiableSet(this.cacheMap.keySet());
                }

                @Override
                public Cache getCache(String name) {
                    Cache cache = this.cacheMap.get(name);
                    if (cache == null && this.dynamic) {
                        synchronized (this.cacheMap) {
                            cache = this.cacheMap.get(name);
                            if (cache == null) {
                                cache = createConcurrentMapCache(name);
                                this.cacheMap.put(name, cache);
                            }
                        }
                    }
                    return cache;
                }

                /**
                 * Create a new ConcurrentMapCache instance for the specified cache name.
                 * 
            @param name the name of the cache
                 * 
            @return the ConcurrentMapCache (or a decorator thereof)
                 
            */
                protected Cache createConcurrentMapCache(String name) {
                    //return new ConcurrentMapCache(name, isAllowNullValues());
                    //此處改用GOOGLE GUAVA的構(gòu)造MANAGER方式
                    return new ConcurrentMapCache(name,
                                                    CacheBuilder.newBuilder()
                                                                .expireAfterWrite(this.expireTime, TimeUnit.MINUTES)
                                                                .maximumSize(this.maximumSize)
                                                                .build()
                                                                .asMap(), 
                                                    isAllowNullValues());
                }

            }


          3. 配置想著bean, cache-concurrentmap-applicationcontext.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:cache
            ="http://www.springframework.org/schema/cache"
                xmlns:p
            ="http://www.springframework.org/schema/p"
                xmlns:c
            ="http://www.springframework.org/schema/c"
                xmlns:jee
            ="http://www.springframework.org/schema/jee"
                xmlns:util
            ="http://www.springframework.org/schema/util"
                xsi:schemaLocation
            ="http://www.springframework.org/schema/context
                      http://www.springframework.org/schema/context/spring-context-3.0.xsd
                      http://www.springframework.org/schema/beans
                      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                      http://www.springframework.org/schema/cache
                      http://www.springframework.org/schema/cache/spring-cache.xsd
                      http://www.springframework.org/schema/jee 
                      http://www.springframework.org/schema/jee/spring-jee.xsd
                      http://www.springframework.org/schema/util
                      http://www.springframework.org/schema/util/spring-util.xsd"
            >

                <cache:annotation-driven />

                <!-- <bean id="cacheManager"
                    class="org.springframework.cache.concurrent.ConcurrentMapCacheManager" >
                    <property name="cacheNames">
                        <list>
                            <value>my-local-cache</value>
                        </list>
                    </property>
                </bean> 
            -->
                
                <bean id="cacheManager"
                    class
            ="com.paul.common.cache.MyConcurrentMapCacheManager">
                    <constructor-arg index="0" value="1" />
                    <constructor-arg index="1" value="5000" />
                </bean>    
                
            </beans>


          4. 通過注釋進行使用
            /*
             * JBoss, Home of Professional Open Source
             * Copyright 2014, Red Hat, Inc. and/or its affiliates, and individual
             * contributors by the @authors tag. See the copyright.txt in the
             * distribution for a full listing of individual contributors.
             *
             * Licensed under the Apache License, Version 2.0 (the "License");
             * you may not use this file except in compliance with the License.
             * You may obtain a copy of the License at
             * 
            http://www.apache.org/licenses/LICENSE-2.0
             * Unless required by applicable law or agreed to in writing, software
             * distributed under the License is distributed on an "AS IS" BASIS,
             * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
             * See the License for the specific language governing permissions and
             * limitations under the License.
             
            */
            package com.paul.springmvc.data;

            import java.util.List;

            import javax.persistence.EntityManager;
            import javax.persistence.criteria.CriteriaBuilder;
            import javax.persistence.criteria.CriteriaQuery;
            import javax.persistence.criteria.Root;

            import org.springframework.beans.factory.annotation.Autowired;
            import org.springframework.cache.annotation.CacheEvict;
            import org.springframework.cache.annotation.Cacheable;
            import org.springframework.stereotype.Repository;
            import org.springframework.transaction.annotation.Transactional;

            import com.paul.springmvc.model.Member;

            @Repository
            @Transactional
            public class MemberDaoImpl implements MemberDao {
                @Autowired
                private EntityManager em;

                @Cacheable(value = "my-local-cache", key = "#id")
                public Member findById(Long id) {
                    System.out.println("MemberDaoImpl NO CACHE");
                    return em.find(Member.class, id);
                }

                public Member findByEmail(String email) {
                    CriteriaBuilder cb = em.getCriteriaBuilder();
                    CriteriaQuery<Member> criteria = cb.createQuery(Member.class);
                    Root<Member> member = criteria.from(Member.class);

                    /*
                     * Swap criteria statements if you would like to try out type-safe criteria queries, a new
                     * feature in JPA 2.0 criteria.select(member).orderBy(cb.asc(member.get(Member_.name)));
                     
            */

                    criteria.select(member).where(cb.equal(member.get("email"), email));
                    return em.createQuery(criteria).getSingleResult();
                }

                public List<Member> findAllOrderedByName() {
                    CriteriaBuilder cb = em.getCriteriaBuilder();
                    CriteriaQuery<Member> criteria = cb.createQuery(Member.class);
                    Root<Member> member = criteria.from(Member.class);

                    /*
                     * Swap criteria statements if you would like to try out type-safe criteria queries, a new
                     * feature in JPA 2.0 criteria.select(member).orderBy(cb.asc(member.get(Member_.name)));
                     
            */

                    criteria.select(member).orderBy(cb.asc(member.get("name")));
                    return em.createQuery(criteria).getResultList();
                }

                @CacheEvict(value="my-local-cache",allEntries=true,beforeInvocation=true)//清空所有緩存
                public void register(Member member) {
                    em.persist(member);
                    return;
                }
            }

          posted on 2015-02-25 16:34 paulwong 閱讀(2697) 評論(0)  編輯  收藏 所屬分類: SPRING性能優(yōu)化緩存

          主站蜘蛛池模板: 洛宁县| 绍兴市| 丹棱县| 轮台县| 宜昌市| 海口市| 仁怀市| 浏阳市| 始兴县| 江源县| 彭阳县| 望谟县| 射洪县| 顺昌县| 谢通门县| 行唐县| 安塞县| 徐闻县| 马关县| 紫金县| 高陵县| 襄汾县| 宁波市| 吉木乃县| 桐乡市| 年辖:市辖区| 万山特区| 陆丰市| 安康市| 皋兰县| 巴马| 高陵县| 德江县| 佛山市| 济阳县| 武川县| 双流县| 金门县| 阆中市| 进贤县| 吴堡县|