0
@RestController
@RequestMapping()
public class AuthController extends BaseController {
    JwtProvider tokenProvider;

    RedisCache<String,UserModel> redisCache;


    @Autowired
    public AuthController(
        JwtProvider tokenProvider,
        MessageHelper messageHelper,
        ModelMapper modelMapper,
        RedisCache<String,UserPrincipalTransformerModel> redisCache
    ) {
        super(AuthController.class, messageHelper, modelMapper);

        this.userService = userService;

        this.tokenProvider = tokenProvider;

        this.loginTokenService = loginTokenService;

        this.companyUserService = companyUserService;

        this.apiKeyService = apiKeyService;

        this.redisCache = redisCache;
    }

I want to store Key value like this, redisCache.put("string",userModel);

can anyone know how to use RedisCache.Class and instantize it, because currently I am getting a error that.

required a bean of type 'io.lettuce.core.support.caching.RedisCache' that could not be found.

Action:

Consider defining a bean of type 'io.lettuce.core.support.caching.RedisCache' in your configuration. .............. But I want to use default RedisCache.class

/*
 * Copyright 2020-2022 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.lettuce.core.support.caching;

/**
 * Interface defining common Redis Cache operations.
 *
 * @param <K> Key type.
 * @param <V> Value type.
 * @author Mark Paluch
 * @since 6.0
 */
public interface RedisCache<K, V> {

    /**
     * Retrieve a {@code value} from Redis for the given cache {@code key}.
     *
     * @param key the key whose associated value is to be returned.
     * @return the value to which this Redis cache value maps the specified key (which may be {@code null} itself), or also
     *         {@code null} if the Redis cache contains no mapping for this key.
     */
    V get(K key);

    /**
     * Associate the specified value with the specified key in this Redis cache.
     *
     * @param key the key with which the specified value is to be associated.
     * @param value the value to be associated with the specified key.
     */
    void put(K key, V value);

    /**
     * Register a invalidation {@code listener} that is notified if a key in this Redis cache expires or gets modified.
     *
     * @param listener the listener to notify.
     */
    void addInvalidationListener(java.util.function.Consumer<? super K> listener);

    /**
     * Closes this Redis cache and releases any connections associated with it. If the cache is already closed then invoking
     * this method has no effect.
     */
    void close();

}

2 Answers2

1

Add redis dependencies

Like always, Spring boot makes things easier with the help of sophisticated starter dependencies. All you have to do is to add the Redis starter.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

Add appropriate settings for the Redis configuration. You can skip the following if you are using Redis locally.

spring.redis.host=localhost
spring.redis.port=8080

In production you may need to add spring.redis.username and spring.redis.password based on your server.

Enable Caching

To enable caching support in Spring boot, first, you need to annotate the main class with @EnableCaching.

@EnableCaching
@SpringBootApplication
public class SpringBootRedisCacheExampleApplication {

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

Add @Cacheable annotation

Find a long-running method and annotate it with @Cacheable. This annotation takes a value which is the cache name. And the key is a unique object to look up the value in cache later.


@Cacheable(value = "items", key = "#id")
public Item getItem(Integer id) {
    Item item = itemRepository.findById(id).orElseThrow(RuntimeException::new);
    logger.info("Loading data from DB {}", item);
    return item;
}

In this case, We used Spring Expression Language(SpEL) to pass the argument value as key.

Add @CacheEvict annotation Once cached, The values stay there indefinitely. Thus, the cache abstraction will never pick updated values from the database. For this reason, you should use @CacheEvict on updates.

@CacheEvict(value = "items", key = "#id")
public Item updateItem(Integer id, Item request) {
    Item item = getItem(id);
    item.setPrice(request.getPrice());
    item.setProductName(request.getProductName());
    return itemRepository.save(item);
}

Once we start the application, The first request goes to the database. And the subsequent requests fetch data from the Redis cache-store. We know this because,

The logs says the records is from the database.

c.s.e.s.cache.service.ItemService:Loading data from DB Item{id=2,productName='Pants Large',price=21.99}
Janil101
  • 306
  • 6
0

Use this as RedisConfiguration, For JedisCluster Mode= enabled, you can also replace this with RedisStandalone for single instance

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.DefaultJedisClientConfig;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import sg.customs.ntp.rsrf.commonservice.util.JedisUtil;

import javax.annotation.PostConstruct;

@Slf4j
@Configuration
public class RedisConfiguration {

    @Value("${spring.data.redis.host:#{''}}")
    private String host;

    @Value("${spring.data.redis.port:#{6379}}")
    private int port;

    @Value("${spring.redis.jedis.pool.max-active-connections:#{8}}")
    private int maxActive;

    @Value("${spring.redis.jedis.pool.max-idle:#{4}}")
    private int maxIdle;

    @Value("${spring.redis.jedis.pool.min-idle:#{1}}")
    private int minIdle;

    @Value("${spring.redis.cluster.max-attempts:#{10}}")
    private int maxAttempts;

    @PostConstruct
    public void getJedisClusterConfiguration() {
        HostAndPort hostAndPort = new HostAndPort(host, port);
        DefaultJedisClientConfig jedisClientConfig = DefaultJedisClientConfig.builder()
                .ssl(true)
                .build();
        GenericObjectPoolConfig<Jedis> genericObjectPoolConfig = new GenericObjectPoolConfig<>();
        genericObjectPoolConfig.setMaxIdle(maxIdle);
        genericObjectPoolConfig.setMaxTotal(maxActive);
        genericObjectPoolConfig.setMinIdle(minIdle);
        JedisUtil.setInstance(new JedisCluster(hostAndPort, jedisClientConfig, maxAttempts, genericObjectPoolConfig));
    }
}

and Use this as JedisUtil

import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.params.SetParams;

@Slf4j
@UtilityClass
public class JedisUtil {
    private static JedisCluster jedisCluster;

    public static void setInstance(JedisCluster cluster) {
        jedisCluster = cluster;
    }

    public void set(String key, String value) {
        try {
            jedisCluster.set(key, value);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
    }

    public void set(String key, String value, long timeToLive) {
        try {
            jedisCluster.set(key, value, new SetParams().ex(timeToLive));
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
    }

    public String get(String key) {
        try {
            return jedisCluster.get(key);
        } catch (Exception e) {
            return null;
        }
    }

    public void del(String key) {
        try {
            jedisCluster.del(key);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
    }
}