ssm+redisは、カスタム注釈+AOPを用いてredisキャッシュをより簡潔に実現する方法

21458 ワード

ssm+maven+redisベースカスタム注釈を使用aopベースAspectJ方式でredisキャッシュを実現
どのようにaopをもっと簡潔に利用してredisキャッシュを実現することができて、話は多くなくて、demoに行きます
需要:データの問合せの時毎回すべてデータベースからデータを問合せなければならなくて、データベースの圧力はとても大きくて、問合せ速度は遅くて、そのためキャッシュ層を設置して、データを問合せする時先にredisの中から問合せて、もし問合せが届かないならば、データベースの中で問合せてそれからデータベースの中で問合せのデータをredisの中で1部に置いて、次回の問合せの時直接redisの中から調べることができて、データベースを問合せする必要はありません
実装プロセス:
まずssmの棚を構築し、redisを導入し、redisキャッシュ方法RedisCacheを作成する.JAvaおよびシーケンス化に使用するツールクラス
カスタム注記getCache目的:この注記にマークされた方法でaopを実現してredis keyが断面@Aspect@Pointcut('@annotation(com.spring_redis.cache.GetCache)を繰り返し記述することを防止する)アクセスポイントは、カスタム注釈、すなわち、その注釈によってマークされる方法ごとに通知される
@Around("getCache())は、周回通知プロセスを使用します.クエリーの場合、先にredisをクエリーします.key-valueが存在する場合は、クエリーが存在しない場合は、データベースをクエリーします.その後、クエリーしたデータをredisキャッシュに格納します.redis keyフォーマット:key競合を防止するため、作成されたkey形式は次のとおりです.
包名类名方法名パラメータの種類パラメータ値",類似"your.package.SomeService.getById(integer).123"
ディレクトリ構造:
maven依存:

            UTF-8
             
            4.0.6.RELEASE
            
            3.2.7
        
  
  
          
        
        
            org.springframework
            spring-core
            ${spring.version}
        

        
            org.springframework
            spring-web
            ${spring.version}
        

        
            org.springframework
            spring-oxm
            ${spring.version}
        

        
            org.springframework
            spring-tx
            ${spring.version}
        

        
            org.springframework
            spring-aop
            ${spring.version}
        

        
            org.springframework
            spring-jdbc
            ${spring.version}
        

        
            org.springframework
            spring-webmvc
            ${spring.version}
        

        
        
            org.springframework
            spring-context-support
            4.0.6.RELEASE
        

        
            org.springframework
            spring-context
            
                
                    commons-logging
                    commons-logging
                
            
            ${spring.version}
        
        
            org.springframework
            spring-test
            ${spring.version}
        
        

          
          
        
            org.aspectj
            aspectjrt
            1.6.12
        
        
            org.aspectj
            aspectjweaver
            1.6.12
        
        
            cglib
            cglib
            2.2
        
          
          
        
            mysql
            mysql-connector-java
            5.1.31
        
          
          
        
            org.apache.commons
            commons-dbcp2
            2.0.1
        

        
        
            org.codehaus.jackson
            jackson-mapper-asl
            1.9.13
        

          
        
            org.mybatis
            mybatis
            ${mybatis.version}
        
        
        
            org.mybatis
            mybatis-spring
            1.2.2
        
  
            
            org.springframework.data  
            spring-data-redis  
            1.6.1.RELEASE  
          
           
            redis.clients  
            jedis  
            2.7.3  
         
  
          
        
            javax.servlet
            javax.servlet-api
            3.0.1
            provided
        
        
            javax.servlet.jsp
            jsp-api
            2.2
            provided
        
        
  
          
            log4j
            log4j
            1.2.17
        
  

ここではredisに関する構成のみを示します
アプリケーションでxmlに追加


        
        
        
        
        
        
        
        
        
        
        
        
        
        
        


        
                
              
              
                    
                    
                    
              
            
            
                
                    
                    
                    
                

                
              
                    
                    
                    
                   
                    
              
              
                    
                    
                        
                    
                    
                        
                    
             
            
            
            
            
            
              
              
                  
              
            
              
               
                   
               
             
             
            
            
            
                
                
                
            
            
              
                   
               
            

 springmvc.xml


    

    
    
    
    
    
    
    
        
        
        
    

    

注記を開くにはspringmvcに書かなければなりません.xmlでは注釈が機能しません
 
そのポイントが始まりました
カスタム注釈の作成
/** 
 *      ,                 
 * @author Chenth 
 */  
@Retention(RetentionPolicy.RUNTIME)  
@Target({ElementType.METHOD})  
public @interface GetCache {  
    String name() default "";  
    String value() default "";  
}

このカスタム注釈でマークされた方法では、次の断面が実現されます.
 
断面の設定
package com.spring_redis.cache;

import java.io.Serializable;
import java.lang.reflect.Method;


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import com.spring_redis.util.RedisCache;

@Component
@Aspect
public class GetCacheAOP  {  
      
    @Autowired
    private RedisTemplate redisTemplate;
    
    private RedisCache redisCache = new RedisCache();
  
      
    @Pointcut("@annotation(com.spring_redis.cache.GetCache)")  
    public void getCache(){
        System.out.println("       ");  
    }  
    
    /** 
     *      @getCache      
     * @param joinPoint 
     */
    @Around("getCache()")
    public Object beforeExec(ProceedingJoinPoint joinPoint){  
        
        
        //  : redis     
        System.out.println("   redis      ...");
        
        //redis key  :    id
        String redisKey = getCacheKey(joinPoint);
        
        //   redis       
        Object objectFromRedis = redisCache.getDataFromRedis(redisKey);
        
        //      
        if(null != objectFromRedis){
            System.out.println(" redis       ...        ");
            return objectFromRedis;
        }
        
        System.out.println("   redis     ...");
        
        //    ,       
        Object object = null;
        try {
            object = joinPoint.proceed();
        } catch (Throwable e) {
            
            e.printStackTrace();
        }
        
        System.out.println("          ...");
        
        //  :            redis 
        System.out.println("              redis    ...");
        
        redisCache.setDataToRedis(redisKey, object);
        System.out.println("redis    ..."+object.toString());
        //         
        return object;
    }
    
    /**
     *     、               
     * @return     "  .  .   .    .   ",   "your.package.SomeService.getById(int).123"
     */
   
    @SuppressWarnings("unused")
    private String getCacheKey(ProceedingJoinPoint joinPoint) {
    
    
        MethodSignature ms=(MethodSignature) joinPoint.getSignature();  
        Method method=ms.getMethod();  
        String ActionName = method.getAnnotation(GetCache.class).name();  
        String fieldList = method.getAnnotation(GetCache.class).value();  
        //System.out.println("   "+ms.toString());
        for (String field:fieldList.split(","))   
             ActionName +="."+field;
    
        //         
        String id = null;
        Object[] args = joinPoint.getArgs();
        if (args != null && args.length > 0) {
            id = String.valueOf(args[0]);
        }
        
        ActionName += "="+id;
        String redisKey = ms+"."+ActionName;
        return redisKey;
    }
    
    
    public void setRedisTemplate(  
            RedisTemplate redisTemplate) {  
        this.redisTemplate = redisTemplate;  
    }
}
@Pointcut("@annotation(com.spring_redis.cache.GetCache)")          
                                           @getCache      
 @Around("getCache()")         ,        redis,          ,             ,      redis 

 
ここではssmフレームワークの構成についてあまり説明していませんが、spring+springmvc+mybatisのフレームワーク統合については後述するかもしれません.
作成mapperレイヤ、serviceレイヤ、controllerレイヤ
  mapper
/**
 * 
 * @author     cmy
 * @date     2016-10-22
 * @description    
 */

public interface RoomMapper {

    @Insert("insert into room(roomName,address) values(#{roomName},#{addRess})")
    int insert(Room room);

    @Select("select * from room where id=#{id}")
    public Room selectByPrimaryKey(@Param("id")Integer id);

}

service
/**
 * 
 * @author     cmy
 * @date     2016-10-22
 * @description test
 */
public interface RoomService {
    
    
    int insert(Room room)throws Exception;
    
    
    Room selectByPrimaryKey(Integer id)throws Exception;
    
}

//   
/**
 * @author         cmy
 * @date         2016-10-22
 * @description  test   
 */
public class RoomServiceImpl implements RoomService{

    @Autowired
    private RoomMapper mapper;
    
    @Override
    public int insert(Room room) throws Exception {
        
        return mapper.insert(room);
    }

    @Override
    public Room selectByPrimaryKey(Integer id) throws Exception {
        
        return mapper.selectByPrimaryKey(id);
    }

    
}

controller
/**
 * 
 * @author     cmy
 * @date     2016-10-22
 * @description test controller
 */

@Controller
@RequestMapping("room")
public class RoomController {

    @Autowired
    private RoomService  roomService;
    
    @GetCache(name="room",value="id")
    @RequestMapping("selectByPrimaryKey")
    public @ResponseBody Object roomList(Integer id) throws Exception{  
        System.out.println("      ,     redis...  "+roomService.selectByPrimaryKey(id).getRoomName());
        return roomService.selectByPrimaryKey(id);
    }
    

}

使用するツールクラスRedisCacheをキャッシュするには:
public class RedisCache {
    
    @Autowired
    private JedisPool jedisPool = new JedisPool();
    

    // redis     ,    
    public Object getDataFromRedis(String redisKey){
        //  
        Jedis jedis = jedisPool.getResource();
        byte[] result = jedis.get(redisKey.getBytes());
        
        //        
        if(null == result){
            return null;
        }
        
        //    ,    
        return SerializeUtil.unSerialize(result);
    }
    
    //             redis
    public void setDataToRedis(String redisKey, Object obj){
        
        //   
        byte[] bytes = SerializeUtil.serialize(obj);
        
        //  redis
        Jedis jedis = jedisPool.getResource();
        String success = jedis.set(redisKey.getBytes(), bytes);
        
        if("OK".equals(success)){
            System.out.println("       redis...");
        }
    }
}

使用するシーケンス化および逆シーケンス化ツールのキャッシュ
/**
 * 
 * @Description:          
 */
public class SerializeUtil {
    /**
     * 
     *    
     */
    public static byte[] serialize(Object obj){
        
        ObjectOutputStream oos = null;
        ByteArrayOutputStream baos = null;
        
        try {
            //   
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            
            oos.writeObject(obj);
            byte[] byteArray = baos.toByteArray();
            return byteArray;
            
        } catch (IOException e) {
            e.printStackTrace();
        }    
        return null;
    }
    
    /**
     * 
     *     
     * @param bytes
     * @return
     */
    public static Object unSerialize(byte[] bytes){
        
        ByteArrayInputStream bais = null;
        
        try {
            //       
            bais = new ByteArrayInputStream(bytes);
            ObjectInputStream ois = new ObjectInputStream(bais);
            return ois.readObject();
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

以上,aop+カスタム注釈を用いてredisキャッシュを実現する過程である.
間違った点があれば、歓迎のメッセージを指摘してください.
参考になる記事:http://www.cnblogs.com/mrlinfeng/p/5857775.html
        http://blog.csdn.net/chentian610/article/details/51012789