今天仔细读了读spring的缓存相关的内容,这里做个总结:
缓存,即一种存储机制,数据可以存放在redis这类nosql的数据库内,存放在本机存储器,存放量相对小,但读取速度非常快。
spring运用的缓存会如AOP一样,准确到方法级别,能明确到哪个方法采用缓存,什么条件下才缓存。
测试所需jar包如下:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>gccSpring</groupId>
<artifactId>gccSpring</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>gccSpring Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.14.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.14.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context-support -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.14.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.4</version>
</dependency>
</dependencies>
<build>
<finalName>gccSpring</finalName>
</build>
</project>
主要为spring核心包,spring上下文包。在支持ehcache时再添加spring支持包,ehcache包。
编写的测试实体如下:
package com.gcc.entity;
/**
* Created by gcc on 2018/2/26.
*/
public class Users {
private int id;
private String name;
private String phoneNumber;
private int age;
public Users() {
}
public Users(int id, String name) {
this.id = id;
this.name = name;
}
public Users(int id, String name, String phoneNumber, int age) {
this.id = id;
this.name = name;
this.phoneNumber = phoneNumber;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Users{" +
"id=" + id +
", name='" + name + '\'' +
", phoneNumber='" + phoneNumber + '\'' +
", age=" + age +
'}';
}
}
get,set方法可以省略,数据通过构造方法注入,这里只是本人强迫症写了下
service类内容如下:
package com.gcc.service;
import com.gcc.entity.Users;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
/**
* Created by gcc on 2018/2/26.
*/
@Service
public class UserService {
private Map<Integer,Users> users = new HashMap<Integer, Users>();
{
users.put(1,new Users(1,"admin"));
users.put(2,new Users(2,"jack"));
users.put(3,new Users(3,"mary"));
users.put(4,new Users(4,"sky","13598789990",20));
users.put(5,new Users(5,"faker","13598789991",21));
}
//服务启动后先添加预定的缓存数据
@Autowired
CacheManager cacheManager;
@PostConstruct
public void setup(){
Cache userCache = cacheManager.getCache("users");
for (Integer key :users.keySet()){
userCache.put(key,users.get(key));
}
}
/**
@Cacheable 查询缓存,对返回结果缓存,默认的value必填,缓存储存器ConcurrentMapCache的名字.condition是缓存条件
@CacheEvict 删除缓存条目,在删除某数据时候可以一同删除缓存
@CachePut 更新缓存条目
@CacheConfig
*/
@Cacheable(value = "users",condition = "#id!=3")
public Users getUser(int id){
System.out.println("get id is:"+id);
return users.get(id);
}
}
用于添加静态数据,初始化填充数据,测试方法为getUser
测试类如下:
package com.gcc.test;
import com.gcc.entity.Users;
import com.gcc.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Created by gcc on 2018/2/26.
*/
public class test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
UserService service = context.getBean(UserService.class);
Users users = service.getUser(1);
System.out.println(users);
Users users2 = service.getUser(1);
System.out.println(users2);
Users users3 = service.getUser(3);
System.out.println(users3);
Users users4 = service.getUser(3);
System.out.println(users4);
Users users5 = service.getUser(4);
System.out.println(users5);
Users users6 = service.getUser(4);
System.out.println(users6);
}
}
第一种方法是通过xml来实例化spring,再获取bean,调用测试类
第二种方法是通过java代码实现spring
第一种方法的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:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<cache:annotation-driven/>
<bean id="userService" class="com.gcc.service.UserService"></bean>
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean id="users" class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"></bean>
</set>
</property>
</bean>
<bean id="ehcacheManger" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="ehcache"></property>
</bean>
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml"></property>
</bean>
</beans>
上方的bean是spring自带的缓存管理器,这里用于测试,set设置的是缓存存放的数据集合名字
下方的bean是企业级别的常用缓存框架,ehcache,设置对应的管理器和初始化工厂。
ehcache.xm简单配置如下:
<ehcache>
<cache name="users" maxElementsInMemory="1000"></cache>
</ehcache>
第二种方法java代码如下:
package com.gcc.tool;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import java.util.Arrays;
/**
* Created by gcc on 2018/2/26.
*/
@Configuration
@ComponentScan(basePackages = {"com.gcc.*"})
@EnableCaching
public class ApplicationConfig {
@Bean
public CacheManager cacheManager(){
SimpleCacheManager cacheManager=new SimpleCacheManager();
cacheManager.setCaches(Arrays.asList(new ConcurrentMapCache("users")));
return cacheManager;
}
}
这里通过代码设置了缓存管理器,并命名ConcurrentMapCache
方式一运行结果如下:
get id is:1
Users{id=1, name='admin', phoneNumber='null', age=0}
Users{id=1, name='admin', phoneNumber='null', age=0}
get id is:3
Users{id=3, name='mary', phoneNumber='null', age=0}
get id is:3
Users{id=3, name='mary', phoneNumber='null', age=0}
get id is:4
Users{id=4, name='sky', phoneNumber='13598789990', age=20}
Users{id=4, name='sky', phoneNumber='13598789990', age=20}
方式二运行结果如下:
Users{id=1, name='admin', phoneNumber='null', age=0}
Users{id=1, name='admin', phoneNumber='null', age=0}
get id is:3
Users{id=3, name='mary', phoneNumber='null', age=0}
get id is:3
Users{id=3, name='mary', phoneNumber='null', age=0}
Users{id=4, name='sky', phoneNumber='13598789990', age=20}
Users{id=4, name='sky', phoneNumber='13598789990', age=20}
说明:因为xml没有加扫描注解的路径范围,所以方式一是扫描不到service的@PostConstruct的,而这注解会在servlet init之前调用,所以方式一不会进行初始化时添加数据