使用maven简单搭建Spring mvc + redis缓存

注:此文参考并整合了网上的文章

《spring缓存机制》:http://blog.csdn.net/sidongxue2/article/details/30516141

《配置 Spring4.0 注解Cache+Redis缓存》:http://blog.csdn.net/ouyhong123/article/details/52162951

spring整合redis缓存,以注解(@Cacheable、@CachePut、@CacheEvict)形式使用》: http://blog.csdn.net/aqsunkai/article/details/51758900   

因为是自己简单搭建的例子,所以一个高级配置(如缓存规则)都没有加。

整个目录的结构如下:

几个重点的文件代码如下:

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zjf</groupId>

    <artifactId>springmvc</artifactId>

    <version>0.0.1-SNAPSHOT</version>

    <packaging>war</packaging>

    <dependencies>

        <dependency>

            <groupId>junit</groupId>

            <artifactId>junit</artifactId>

            <version>4.8.2</version>

            <scope>test</scope>

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-webmvc</artifactId>

            <version>4.3.0.RELEASE</version>

        </dependency>

        <dependency>

            <groupId>redis.clients</groupId>

            <artifactId>jedis</artifactId>

            <version>2.8.1</version>

        </dependency>

        <dependency>

            <groupId>org.springframework.data</groupId>

            <artifactId>spring-data-redis</artifactId>

            <version>1.7.2.RELEASE</version>

        </dependency>

    </dependencies>

</project>

web.xml:

<?xml version="1.0" encoding="UTF-8"?>

<web-app id="WebApp_ID" version="3.0"

    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

    <context-param>

        <param-name>contextConfigLocation</param-name>

        <param-value>/WEB-INF/config/applicationContext.xml</param-value>

    </context-param>

    <listener>

        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

    </listener>

    <servlet>

        <servlet-name>spring</servlet-name>

        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <init-param>

           <param-name>contextConfigLocation</param-name>

           <param-value>/WEB-INF/config/spring-servlet.xml</param-value>

        </init-param>

        <load-on-startup>1</load-on-startup>

    </servlet>

    <servlet-mapping>

        <servlet-name>spring</servlet-name>

        <url-pattern>/</url-pattern>

    </servlet-mapping>

</web-app>

spring-servlet.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:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"

    xsi:schemaLocation="http://www.springframework.org/schema/beans

       http://www.springframework.org/schema/beans/spring-beans.xsd

       http://www.springframework.org/schema/context

       http://www.springframework.org/schema/context/spring-context.xsd

       http://www.springframework.org/schema/tx

       http://www.springframework.org/schema/tx/spring-tx.xsd

          http://www.springframework.org/schema/mvc

       http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 配置扫描的包 -->

    <context:component-scan base-package="com.zjf.*" />

    <!-- 注册HandlerMapper、HandlerAdapter两个映射类 -->

    <mvc:annotation-driven />

    <!-- 访问静态资源 -->

    <mvc:default-servlet-handler />

   

    <!-- 视图解析器 -->

    <bean

        class="org.springframework.web.servlet.view.InternalResourceViewResolver">

        <property name="prefix" value="/WEB-INF/view/"></property>

        <property name="suffix" value=".jsp"></property>

    </bean>

</beans>

 

 

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:p="http://www.springframework.org/schema/p"   

    xmlns:context="http://www.springframework.org/schema/context"   

    xmlns:mvc="http://www.springframework.org/schema/mvc"   

    xmlns:cache="http://www.springframework.org/schema/cache" 

    xsi:schemaLocation="http://www.springframework.org/schema/beans     

                        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd     

                        http://www.springframework.org/schema/context     

                        http://www.springframework.org/schema/context/spring-context-4.2.xsd     

                        http://www.springframework.org/schema/mvc     

                        http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd 

                        http://www.springframework.org/schema/cache  

                        http://www.springframework.org/schema/cache/spring-cache-4.2.xsd">  

     <!-- 应用spring cache注解功能  --> 

    <cache:annotation-driven /> 

    <context:property-placeholder location="classpath:redis.properties" />

   

    <!-- jedis 配置 --> 

   <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"

       <property name="maxIdle" value="${redis.maxIdle}" /> 

       <!--<property name="maxWaitMillis" value="${redis.maxWait}" />--> 

       <property name="testOnBorrow" value="${redis.testOnBorrow}" /> 

   </bean> 

   <!-- redis服务器中心 --> 

   <bean id="connectionFactory" 

       class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"

       <property name="poolConfig" ref="poolConfig" /> 

       <property name="port" value="${redis.port}" /> 

       <property name="hostName" value="${redis.hostname}" /> 

       <!-- <property name="password" value="${redis.password}" /> --> 

       <property name="timeout" value="${redis.timeout}"></property> 

   </bean> 

  

   <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"

       <property name="connectionFactory" ref="connectionFactory" /> 

       <property name="keySerializer"

           <bean 

               class="org.springframework.data.redis.serializer.StringRedisSerializer" /> 

       </property> 

       <property name="valueSerializer"

           <bean 

               class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" /> 

       </property> 

   </bean> 

  

    <!-- 创建spring cache bean --> 

    <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"

        <property name="caches"

            <set> 

                <bean 

                    class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" 

                    p:name="default" /> 

                

                     <bean class="com.zjf.util.RedisCache">   

                     <property name="redisTemplate" ref="redisTemplate" />   

                     <property name="name" value="data"/>   

                     <!-- common名称要在类或方法的注解中使用 --> 

                </bean>  

            </set> 

        </property> 

    </bean> 

   

    <!-- 创建User Dao bean --> 

    <bean id="userDao" class="com.zjf.spring.cache.dao.impl.UserDaoImpl" ></bean> 

    <!-- 创建User Service bean --> 

    <bean id="userService" class="com.zjf.spring.cache.service.impl.UserServiceImpl"

        <property name="userDao"

            <ref bean="userDao"></ref> 

         </property> 

    </bean>  

</beans> 

UserServiceImpl.java:

package com.zjf.spring.cache.service.impl;

import java.util.Map;

import org.springframework.cache.annotation.CacheEvict;

import org.springframework.cache.annotation.Cacheable;

import com.zjf.spring.cache.dao.UserDao;

import com.zjf.spring.cache.model.User;

import com.zjf.spring.cache.service.UserService;

public class UserServiceImpl implements UserService { 

       

    private UserDao userDao; 

     

    /**

     * JVM加载spring配置文件时, 通过set方法注入本类的依赖.

     * @param userDao

     */ 

    public void setUserDao(UserDao userDao) { 

        this.userDao = userDao; 

    } 

    /**

     * 对数据进行增删改时清空缓存, 查询时使用缓存, 其中value为缓存区,

     * allEntries表示清空缓存中所有的数据.

     */ 

   

    @CacheEvict(value = "data", allEntries = true)    

    public void add(User user) { 

        System.out.println("UserService: method- add(User user)" ); 

        userDao.add(user); 

    } 

   

    @CacheEvict(value = "data", allEntries = true)   

    public void delete(String id) { 

        System.out.println("UserService: method-delete(String id)" ); 

        userDao.delete(id); 

    } 

   

    @CacheEvict(value = "data", allEntries = true)   

    public void update(User user) { 

        System.out.println("UserService: method-update(User user)" ); 

        userDao.update(user); 

    } 

   

    @Cacheable(value = "data")    

    public User find(String id) { 

        System.out.println("UserService: method-find(String id)" ); 

        return userDao.find(id); 

    } 

   

    @Cacheable(value = "data")   

    public Map<String, User> getAll() { 

        System.out.println("UserService: method-getAll()" ); 

        return userDao.getAll(); 

    } 

redis.properties

#redis config 

#redis.hostname=192.168.242.131   

redis.hostname=192.168.1.101 

redis.port=6379   

redis.timeout=2000 

redis.usePool=true 

redis.default.db=0 

#u6700u5927u5206u914Du7684u5BF9u8C61u6570    

redis.maxTotal=600 

#u6700u5927u80FDu591Fu4FDDu6301idelu72B6u6001u7684u5BF9u8C61u6570   

redis.maxIdle=300  

#u591Au957Fu65F6u95F4u68C0u67E5u4E00u6B21u8FDEu63A5u6C60u4E2Du7A7Au95F2u7684u8FDEu63A5 

redis.timeBetweenEvictionRunsMillis=30000   

#u7A7Au95F2u8FDEu63A5u591Au957Fu65F6u95F4u540Eu4F1Au88ABu6536u56DE 

redis.minEvictableIdleTimeMillis=30000  

#u5F53u8C03u7528borrow Objectu65B9u6CD5u65F6uFF0Cu662Fu5426u8FDBu884Cu6709u6548u6027u68C0u67E5   

redis.testOnBorrow=true  

########reidsu7F16u7801u683Cu5F0F 

redis.encode=utf-8 

######u7F13u5B58u8FC7u671Fu65F6u95F4 u79D2  1000*60*60*24*7 u4E03u5929 

redis.expire=604800000 

####u662Fu5426u5F00u542FRedisu670Du52A1u5E94u7528 

redis.unlock=false 

DemoController.java:

 

package com.zjf.spring.cache;

 

import java.util.List;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

 

import com.zjf.spring.cache.model.User;

import com.zjf.spring.cache.service.UserService;

 

 

 

@Controller

public class DemoController {

 

     

      @Autowired

      private  UserService userService;

      @RequestMapping("/finduser")

      public String finduser() {

           User user = userService.find("2"); 

          System.out.println(user); 

           return "finduser";

      }

     

      @RequestMapping("/adduser")

      public String adduser() {

           userService.add(new User("2", "Ilucky1", "pwd1")); 

           return "adduser";

      }

}

 

执行结果:

tomcat服务启动后,先进入http://localhost:8080/springmvc/adduser页面,这时候会在dao层插入一个user。

然后进入http://localhost:8080/springmvc/finduser页面,因为第一次进入,还没有缓存,这时候会进入service和dao。

再次进入http://localhost:8080/springmvc/finduse 页面,这个时候发现,没有进入service。直接取了redis缓存。

控制台打印的结果如下:

UserService: method- add(User user)

UserDao method- add(User user)

UserService: method-find(String id)

UserDao method- find(String id)

2-Ilucky1-pwd1

2-Ilucky1-pwd1

 

注意:第二次打印2-Ilucky1-pwd1的时候,前面没有进入UserService和UserDao的打印。

这个时候我们去redis服务器上看redis的缓存。

127.0.0.1:6379> keys *

1) "2"

注意:keys*命令可以获取所有的key。这里我们看到key为2.因为我们执行UserService: method-find(String id)方法的时候,传入的参数是2.这样来看,spring是通过参数来作为key的,如果有两个不同的方法,参数一样,那么缓存会冲突才对。所以还是定义@Cacheable注解的时候,还是把key也加上。

@Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存

@Cacheable 主要的参数
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 例如:
@Cacheable(value=”mycache”) 或者 
@Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 例如:
@Cacheable(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 例如:
@Cacheable(value=”testcache”,condition=”#userName.length()>2”)
------------------------------------------------------------
--////////////////////////////////////////////////////////////////////////////////
表 2. @CachePut 作用和配置方法

@CachePut 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用

@CachePut 主要的参数
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 例如:
@Cacheable(value=”mycache”) 或者 
@Cacheable(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 例如:
@Cacheable(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 例如:
@Cacheable(value=”testcache”,condition=”#userName.length()>2”)
//////////////////////////////////////////////////////
 
表 3. @CacheEvict 作用和配置方法

@CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空

@CacheEvict 主要的参数
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 例如:
@CachEvict(value=”mycache”) 或者 
@CachEvict(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 例如:
@CachEvict(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才清空缓存 例如:
@CachEvict(value=”testcache”,
condition=”#userName.length()>2”)
allEntries 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 例如:
@CachEvict(value=”testcache”,allEntries=true)
beforeInvocation 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 例如:
@CachEvict(value=”testcache”,beforeInvocation=true)

整个代码的下载:

http://download.csdn.net/detail/xiaolang8762400/9857058

 

 

原文地址:https://www.cnblogs.com/xiaolang8762400/p/6928318.html