簡單實用springboot自帶的緩存

1,沒有引入緩存中間件的話,springboot會使用SimpleCacheConfiguration

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

①,pom依賴mysql

<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#CacheConfigurationImportSelectorweb

這個靜態內部類看出springboot能夠讓咱們配置哪些緩存,spring

源碼以下:sql

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;
		}

	}

能夠經過debug=true 查看springboot爲咱們加載了哪些類apache

 

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沒有起效springboot

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 的相關方法打上斷點

①,重點是以下代碼mybatis

//經過這行代碼,咱們知道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 不會走緩存,第二次就走走緩存了app

#第一次訪問,打印的日誌
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
相關文章
相關標籤/搜索