Spring Cache入门应用

        刚刚接触Spring Cache功能,发现网上很多博客,都没有入门级应用介绍,所以花了一些时间整理了一下。关于cache基本功能用法,可自行百度。

一、工程准备

创建一个springboot工程

1.1、pom.xml

采用web服务进行校验

    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.4.5</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

1.2、 入口函数

@SpringBootApplication
public class Hello {

    public static void main(String[] args) {
        SpringApplication.run(Hello.class, args);
    }
}

1.3、web服务 

@RestController
public class HelloController {
    @Resource
    private ComputerService service;

    /**
     * http://127.0.0.1:8080/hello
     */
    @RequestMapping("/hello")
    public String Hello() {
        return "hello world";
    }

    /**
     * http://127.0.0.1:8080/plus?a=1&b=2
     */
    @RequestMapping("/plus")
    public int Plus(@RequestParam int a, @RequestParam int b) {
        return service.plus(a, b);
    }
}
@Service
public class ComputerService {
    private final static Logger logger = LoggerFactory.getLogger(ComputerService.class);
    
    public int plus(int a, int b) {
        logger.info("plus, a={}, b={}", a, b);
        return a + b;
    }
}

验证结果,会有日志输出:

2021-08-31 17:58:25.337  INFO 67530 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2021-08-31 17:58:25.337  INFO 67530 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2021-08-31 17:58:25.338  INFO 67530 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
2021-08-31 17:58:25.360  INFO 67530 --- [nio-8080-exec-1] c.m.hello.service.ComputerService        : plus, a=1, b=2
2021-08-31 17:58:28.553  INFO 67530 --- [nio-8080-exec-2] c.m.hello.service.ComputerService        : plus, a=1, b=2

 二、简单应用

要想应用cache功能,需要做如下操作:

1)注入CacheManager管理对象

2)启用cache功能 @EnableCaching

3)标注方法,@Cacheable

2.1、注入CacheManager管理对象 

@Configuration
public class CacheConfig {

    @Bean
    public CacheManager createCacheManger() {
        SimpleCacheManager mgr = new SimpleCacheManager();
        List<Cache> caches = new ArrayList<>();
        caches.add(new ConcurrentMapCache("plus")); //设置cache名称,这里需要注意,后面会用到
        mgr.setCaches(caches);
        return mgr;
    }
}

2.2、启用@EnableCaching

在入口函数类,进行注入

@SpringBootApplication
@EnableCaching
public class Hello {

    public static void main(String[] args) {
        SpringApplication.run(Hello.class, args);
    }
}

2.3、标注方法

@Service
public class ComputerService {
    private final static Logger logger = LoggerFactory.getLogger(ComputerService.class);

    @Cacheable(cacheNames = "plus", key = "#a")
    public int plus(int a, int b) {
        logger.info("plus, a={}, b={}", a, b);
        return a + b;
    }
}

 运行查看效果,发现只有第一次会有打印:

2021-08-31 18:06:45.428  INFO 68983 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2021-08-31 18:06:45.428  INFO 68983 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2021-08-31 18:06:45.429  INFO 68983 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
2021-08-31 18:06:45.458  INFO 68983 --- [nio-8080-exec-1] c.m.hello.service.ComputerService        : plus, a=1, b=2

 三、自定义cache

上面例子,使用的是spring自带的cache组件,当然也有开源组件比如redis的,但是如果自己实现一套cache应该怎么实现呢。这个并不是很复杂,下面一起看一下。

spring提供两个接口:Cache和CacheManager两个接口,这两个接口在spring中都实现。

public class CacheImpl implements Cache {
    private final static Logger LOG = LoggerFactory.getLogger(CacheImpl.class);
    private String name;
    private Map<Object, Object> map = new ConcurrentHashMap<>();
    public CacheImpl(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public Object getNativeCache() {
        return map;
    }

    @Override
    public ValueWrapper get(Object o) {
        Object v = map.get(o);
        if (v != null) {
            return new ValueWrapper() {
                @Override
                public Object get() {
                    LOG.info("get o");
                    return v;
                }
            };
        } else {
            return null;
        }

    }

    @Override
    public <T> T get(Object o, Class<T> aClass) {
        LOG.info("get class");
        Object v = this.map.get(o);
        if (aClass != null && aClass == v.getClass()) {
            return (T)v;
        }
        return null;
    }

    @Override
    public <T> T get(Object o, Callable<T> callable) {
        return null;
    }

    @Override
    public void put(Object o, Object o1) {
        LOG.info("PUT");
        this.map.put(o, o1);
    }

    @Override
    public void evict(Object o) {
        this.map.remove(o);
    }

    @Override
    public void clear() {
        this.map.clear();
    }
}
public class MyCacheManager implements CacheManager {
    Map<String, Cache> maps = new HashMap<>();

    @Override
    public Cache getCache(String s) {
        return maps.get(s);
    }

    @Override
    public Collection<String> getCacheNames() {
        return maps.keySet();
    }

    public void setCaches(List<Cache> caches) {
        caches.forEach(e -> maps.put(e.getName(), e));
    }
}

运行效果,与上面是一致的。

猜你喜欢

转载自blog.csdn.net/xxb249/article/details/120023316
今日推荐