简单实用springboot自带的缓存

1,没有引入缓存中间件的话,springboot会使用SimpleCacheConfiguration

springboot版本:2.0.2.RELEASE,1.5.x 同理

①,pom依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
 <dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-starter</artifactId>
	<version>1.3.2</version>
</dependency>

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
</dependency>

②,我们可以观察CacheAutoConfiguration#CacheConfigurationImportSelector

这个静态内部类看出springboot可以让我们配置哪些缓存,

源码如下:

	static class CacheConfigurationImportSelector implements ImportSelector {

		@Override
		public String[] selectImports(AnnotationMetadata importingClassMetadata) {
            //通过CacheType 获取支持的缓存类型,注意,是有序的从上到下
			CacheType[] types = CacheType.values();
			String[] imports = new String[types.length];
			for (int i = 0; i < types.length; i++) {
				imports[i] = CacheConfigurations.getConfigurationClass(types[i]);
			}
			return imports;
		}

	}

194729_QNzp_3574106.png

可以通过debug=true 查看springboot为我们加载了哪些类

 

2,启用springboot的缓存注解

//在主配置类上加上,@EnableCaching,使得缓存注解生效
@EnableCaching
@SpringBootApplication
public class SpringbootCacheApplication {

 

3,在service层的对应方法加上缓存注解

@Service
public class EmployeeService {

    @Autowired
    private EmployeeDao employeeDao;
    
    //缓存的key,默认就是传入的id,更多用法请自行百度
    @Cacheable(cacheNames = "emp")
    public Employee findById(Integer id) {
        System.out.println("查找key为:"+id);
        return employeeDao.findById(id);
    }
}

4,controller 编写对应的测试代码

@RestController
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;

    @RequestMapping("find/{id}")
    public Employee findById(@PathVariable("id")Integer id){

        return employeeService.findById(id);
    }
}

5,启动springboot应用

①,在application.properties 开启debug模式

debug=true

②,通过观察控制台看到只有SimpleCacheConfiguration 是起效了,其余xxCacheConfiguration没有起效

195925_hVL6_3574106.png

6,给对应cache打上对应断点,在验证是否启用了该缓存

//ConcurrentMapCacheManager配置了	ConcurrentMapCacheManager 作为缓存管理器
@Bean
	public ConcurrentMapCacheManager cacheManager() {
		ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager();
		List<String> cacheNames = this.cacheProperties.getCacheNames();
		if (!cacheNames.isEmpty()) {
			cacheManager.setCacheNames(cacheNames);
		}
		return this.customizerInvoker.customize(cacheManager);
	}

//进入ConcurrentMapCacheManager  类,
//这个就是ConcurrentMapCacheManager  获取缓存的方法

@Override
	@Nullable
	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;
	}
//点击createConcurrentMapCache ,可以看到ConcurrentMapCacheManager  创建的cache为ConcurrentMapCache

protected Cache createConcurrentMapCache(String name) {
		SerializationDelegate actualSerialization = (isStoreByValue() ? this.serialization : null);
		return new ConcurrentMapCache(name, new ConcurrentHashMap<>(256),
				isAllowNullValues(), actualSerialization);

}

7,给ConcurrentMapCache 的相关方法打上断点

①,重点是如下代码

//通过这行代码,我们知道SimpleCacheConfiguration是用ConcurrentMap来存储缓存的,
//(mybatis的二级缓存也是用map存储的)
//所以,我们可以得出SimpleCacheConfiguration 是内存缓存,相当于memorycache,不会持久化缓存
private final ConcurrentMap<Object, Object> store;

//获取缓存
protected Object lookup(Object key) {
		return this.store.get(key);
	}

	
//设置缓存
	@Override
	public void put(Object key, @Nullable Object value) {
		this.store.put(key, toStoreValue(value));
	}

8,测试结果

第一次访问http://127.0.0.1:8979/find/1 不会走缓存,第二次就走走缓存了

#第一次访问,打印的日志
2018-05-19 20:09:51.979  INFO 1736 --- [nio-8979-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2018-05-19 20:09:51.979  INFO 1736 --- [nio-8979-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2018-05-19 20:09:52.004  INFO 1736 --- [nio-8979-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 25 ms
2018-05-19 20:09:52.012 DEBUG 1736 --- [nio-8979-exec-1] o.s.b.w.s.f.OrderedRequestContextFilter  : Bound request context to thread: org.apache.catalina.connector.RequestFacade@20e4d465
查找key为:1
2018-05-19 20:09:56.382  INFO 1736 --- [nio-8979-exec-1] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2018-05-19 20:09:56.513  INFO 1736 --- [nio-8979-exec-1] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2018-05-19 20:09:56.517 DEBUG 1736 --- [nio-8979-exec-1] c.c.s.emp.dao.EmployeeDao.findById       : ==>  Preparing: select * from emp where id=?; 
2018-05-19 20:09:56.529 DEBUG 1736 --- [nio-8979-exec-1] c.c.s.emp.dao.EmployeeDao.findById       : ==> Parameters: 1(Integer)
2018-05-19 20:09:56.538 DEBUG 1736 --- [nio-8979-exec-1] c.c.s.emp.dao.EmployeeDao.findById       : <==      Total: 1

#第二次访问,打印的日志
2018-05-19 20:10:49.643 DEBUG 1736 --- [nio-8979-exec-5] o.s.b.w.s.f.OrderedRequestContextFilter  : Bound request context to thread: org.apache.catalina.connector.RequestFacade@20e4d465
2018-05-19 20:10:49.645 DEBUG 1736 --- [nio-8979-exec-5] o.s.b.w.s.f.OrderedRequestContextFilter  : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@20e4d465
2018-05-19 20:10:49.650 DEBUG 1736 --- [nio-8979-exec-8] o.s.b.w.s.f.OrderedRequestContextFilter  : Bound request context to thread: org.apache.catalina.connector.RequestFacade@20e4d465
2018-05-19 20:10:49.653 DEBUG 1736 --- [nio-8979-exec-8] o.s.b.w.s.f.OrderedRequestContextFilter  : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@20e4d465

 

转载于:https://my.oschina.net/u/3574106/blog/1815387

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值