Code Monkey home page Code Monkey logo

jetcache's Introduction

Java CI with Maven Coverage Status GitHub release License Project Map

Introduction

JetCache is a Java cache abstraction which provides uniform usage for different caching solutions. It provides more powerful annotations than those in Spring Cache. The annotations in JetCache supports native TTL, two level caching, and automatically refresh in distrubuted environments, also you can manipulate Cache instance by your code. Currently, there are four implementations: RedisCache, TairCache(not open source on github), CaffeineCache (in memory) and a simple LinkedHashMapCache (in memory). Full features of JetCache:

  • Manipulate cache through uniform Cache API.
  • Declarative method caching using annotations with TTL(Time To Live) and two level caching support
  • Create & configure Cache instance with cache manager
  • Automatically collect access statistics for Cache instance and method level cache
  • The strategy of key generation and value serialization can be customized
  • Cache key convertor supported: fastjson/fastjson2/jackson; Value convertor supported: java/kryo/kryo5
  • Distributed cache auto refresh and distributed lock. (2.2+)
  • Asynchronous access using Cache API (2.2+, with redis lettuce client)
  • Invalidate local caches (in all JVM process) after updates (2.7+)
  • Spring Boot support

requirements:

  • JDK1.8
  • Spring Framework4.0.8+ (optional, with annotation support),jetcache 2.7 need 5.2.4+
  • Spring Boot1.1.9+ (optional), jetcache 2.7 need 2.2.5+

Visit docs for more details.

Getting started

Method cache

Declare method cache using @Cached annotation.
expire = 3600 indicates that the elements will expire in 3600 seconds after being set. JetCache automatically generates the cache key with all the parameters.

public interface UserService {
    @Cached(expire = 3600, cacheType = CacheType.REMOTE)
    User getUserById(long userId);
}

Using key attribute to specify cache key using SpEL script.

public interface UserService {
    @Cached(name="userCache-", key="#userId", expire = 3600)
    User getUserById(long userId);

    @CacheUpdate(name="userCache-", key="#user.userId", value="#user")
    void updateUser(User user);

    @CacheInvalidate(name="userCache-", key="#userId")
    void deleteUser(long userId);
}

In order to use parameter name such as key="#userId", you javac compiler target must be 1.8 and above, and the -parameters should be set. Otherwise, use index to access parameters like key="args[0]"

Auto refreshment:

public interface SummaryService{
    @Cached(expire = 3600, cacheType = CacheType.REMOTE)
    @CacheRefresh(refresh = 1800, stopRefreshAfterLastAccess = 3600, timeUnit = TimeUnit.SECONDS)
    @CachePenetrationProtect
    BigDecimal summaryOfToday(long categoryId);
}

CachePenetrationProtect annotation indicates that the cache will be loaded synchronously in multi-thread environment.

Cache API

Create a Cache instance with CacheManager:

@Autowired
private CacheManager cacheManager;
private Cache<String, UserDO> userCache;

@PostConstruct
public void init() {
    QuickConfig qc = QuickConfig.newBuilder("userCache")
        .expire(Duration.ofSeconds(100))
        .cacheType(CacheType.BOTH) // two level cache
        .localLimit(50)
        .syncLocal(true) // invalidate local cache in all jvm process after update
        .build();
    userCache = cacheManager.getOrCreateCache(qc);
}

The code above create a Cache instance. cacheType = CacheType.BOTH define a two level cache (a local in-memory-cache and a remote cache system) with local elements limited upper to 50(LRU based evict). You can use it like a map:

UserDO user = userCache.get(12345L);
userCache.put(12345L, loadUserFromDataBase(12345L));
userCache.remove(12345L);

userCache.computeIfAbsent(1234567L, (key) -> loadUserFromDataBase(1234567L));

Advanced API

Asynchronous API:

CacheGetResult r = cache.GET(userId);
CompletionStage<ResultData> future = r.future();
future.thenRun(() -> {
    if(r.isSuccess()){
        System.out.println(r.getValue());
    }
});

Distributed lock:

cache.tryLockAndRun("key", 60, TimeUnit.SECONDS, () -> heavyDatabaseOperation());

Read through and auto refresh:

@Autowired
private CacheManager cacheManager;
private Cache<String, Long> orderSumCache;

@PostConstruct
public void init() {
    QuickConfig qc = QuickConfig.newBuilder("userCache")
        .expire(Duration.ofSeconds(3600))
        .loader(this::loadOrderSumFromDatabase)
        .refreshPolicy(RefreshPolicy.newPolicy(60, TimeUnit.SECONDS).stopRefreshAfterLastAccess(100, TimeUnit.SECONDS))
        .penetrationProtect(true)
        .build();
    orderSumCache = cacheManager.getOrCreateCache(qc);
}

Configuration with Spring Boot

pom:

<dependency>
    <groupId>com.alicp.jetcache</groupId>
    <artifactId>jetcache-starter-redis</artifactId>
    <version>${jetcache.latest.version}</version>
</dependency>

App class:

@SpringBootApplication
@EnableMethodCache(basePackages = "com.company.mypackage")
@EnableCreateCacheAnnotation // deprecated in jetcache 2.7, can be removed if @CreateCache is not used
public class MySpringBootApp {
    public static void main(String[] args) {
        SpringApplication.run(MySpringBootApp.class);
    }
}

spring boot application.yml config:

jetcache:
  statIntervalMinutes: 15
  areaInCacheName: false
  local:
    default:
      type: linkedhashmap #other choose:caffeine
      keyConvertor: fastjson2 #other choose:fastjson/jackson
      limit: 100
  remote:
    default:
      type: redis
      keyConvertor: fastjson2 #other choose:fastjson/jackson
      broadcastChannel: projectA
      valueEncoder: java #other choose:kryo/kryo5
      valueDecoder: java #other choose:kryo/kryo5
      poolConfig:
        minIdle: 5
        maxIdle: 20
        maxTotal: 50
      host: ${redis.host}
      port: ${redis.port}

Visit detail configuration for more instructions

More docs

Visit docs for more details.

For upgrade see changelog and compatibility notes.

jetcache's People

Contributors

areyouok avatar hadoop835 avatar roiocam avatar dependabot[bot] avatar zt9788 avatar jeasonyoung avatar rotbor avatar darknesstm avatar dylan-tao avatar amjad1210 avatar charlesvhe avatar chenchi2038 avatar cpugputpu avatar javalover123 avatar xiaolongyuan avatar sao-broken-legs avatar scolia avatar xiezheng-xd avatar chunmenglu avatar magestacks avatar codejam-cn avatar devefx avatar ivan97 avatar w-a-n-g-s-h-u-n avatar kenvifire avatar hhhhhhgggggg avatar celebrate-future avatar blindpirate avatar awei2020 avatar pthariensflame avatar

Watchers

James Cloos avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.