java 如何自动装配 RedisTemplate<String,Long>

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27521672/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 11:56:37  来源:igfitidea点击:

How autowired RedisTemplate<String,Long>

javaspringspring-mvcredis

提问by yo_nas

I want to use RedisTemplate on spring boot. I can use StringRedeisTemplate successfully, but when i cant use RedisTemplate . here is the code.

我想在春季启动时使用 RedisTemplate。我可以成功使用 StringRedeisTemplate ,但是当我不能使用 RedisTemplate 时。这是代码。

@Service
public class MyService {

    @Autowired
    private RedisTemplate<String, Long> template;

    public void execute() {
        template.opsForValue().set("hoge", 1l);
    }
}

But, when start apps, get errors.

但是,当启动应用程序时,会出错。

> Exception in thread "main"
> org.springframework.beans.factory.BeanCreationException: Error
> creating bean with name 'MyService': Injection of autowired
> dependencies failed; nested exception is
> org.springframework.beans.factory.BeanCreationException: Could not
> autowire field: private
> org.springframework.data.redis.core.RedisTemplate
> org.hoge.service.MyService.template; nested exception is
> org.springframework.beans.factory.NoSuchBeanDefinitionException: No
> qualifying bean of type
> [org.springframework.data.redis.core.RedisTemplate] found for
> dependency: expected at least 1 bean which qualifies as autowire
> candidate for this dependency. Dependency annotations:
> {@org.springframework.beans.factory.annotation.Autowired(required=true)}
>   at
> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
>   at
> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1202)
>   at
> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
>   at
> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
>   at
> org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:302)
>   at
> org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
>   at
> org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
>   at
> org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
>   at
> org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:762)
>   at
> org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
>   at
> org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
>   at
> org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
>   at
> org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
>   at
> org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
>   at
> org.springframework.boot.SpringApplication.run(SpringApplication.java:961)
>   at
> org.springframework.boot.SpringApplication.run(SpringApplication.java:950)
>   at
> jp.bizreach.davide.recommend.application.DavimendApplication.main(DavimendApplication.java:11)
>   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
>   at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>   at java.lang.reflect.Method.invoke(Method.java:483)     at
> com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
> Caused by: org.springframework.beans.factory.BeanCreationException:
> Could not autowire field: private
> org.springframework.data.redis.core.RedisTemplate
> org.hoge.service.MyService.template; nested exception is
> org.springframework.beans.factory.NoSuchBeanDefinitionException: No
> qualifying bean of type
> [org.springframework.data.redis.core.RedisTemplate] found for
> dependency: expected at least 1 bean which qualifies as autowire
> candidate for this dependency. Dependency annotations:
> {@org.springframework.beans.factory.annotation.Autowired(required=true)}
>   at
> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:558)
>   at
> org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
>   at
> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
>   ... 21 more Caused by:
> org.springframework.beans.factory.NoSuchBeanDefinitionException: No
> qualifying bean of type
> [org.springframework.data.redis.core.RedisTemplate] found for
> dependency: expected at least 1 bean which qualifies as autowire
> candidate for this dependency. Dependency annotations:
> {@org.springframework.beans.factory.annotation.Autowired(required=true)}
>   at
> org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1308)
>   at
> org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1054)
>   at
> org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:949)
>   at
> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:530)
>   ... 23 more

采纳答案by sol4me

The stacktrace suggest that you haven't defined the Bean which you will like to use for injecting in RedisTemplate.You can resolve it creating a configuration file, E.g.

堆栈跟踪表明您尚未定义要用于注入的 Bean RedisTemplate。您可以通过创建配置文件来解决它,例如

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericToStringSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class AppConfig {
 @Bean
 JedisConnectionFactory jedisConnectionFactory() {
  return new JedisConnectionFactory();
 }

 @Bean
 RedisTemplate< String, Long > redisTemplate() {
  final RedisTemplate< String, Long > template =  new RedisTemplate< String, Long >();
  template.setConnectionFactory( jedisConnectionFactory() );
  template.setKeySerializer( new StringRedisSerializer() );
  template.setHashValueSerializer( new GenericToStringSerializer< Long >( Long.class ) );
  template.setValueSerializer( new GenericToStringSerializer< Long >( Long.class ) );
  return template;
 }
}

Once you have the configuration file then you need to pass it to SpringApplication.runE.g.

获得配置文件后,您需要将其传递给SpringApplication.runEg

Object[] sources = {AppConfig.class};
ApplicationContext ctx = SpringApplication.run(sources, args);

回答by nsdiv

If you use Spring boot, add a dependency to spring-boot-starter-redis, which will bring in the redisTemplate bean. However, that bean is of type RedisTemplate<Object, Object>,

如果使用 Spring boot,则在 spring-boot-starter-redis 中添加一个依赖项,它会引入 redisTemplate bean。但是,那个 bean 的类型是RedisTemplate<Object, Object>

So create another bean for the operations that you need, as shown here enter link description here

因此,为您需要的操作创建另一个 bean,如下所示在此处输入链接描述

回答by Bruce

You can do as sol4mesaid on the top, but you can handle this in a easy way:

你可以按照上面sol4me说的做,但你可以用一种简单的方式来处理:

1, auto wire RedisTemplate

1、汽车线材 RedisTemplate

@Autowired
private RedisTemplate redisTemplate;

2, set value like this:

2、设置值如下:

redisTemplate.opsForValue().set("yourkey", 12434L);

3, get value like this:

3、获取值如下:

(Long) redisTemplate.opsForValue().get("yourkey");

No need to create a bean like RedisTemplate< String, Long >, if you do this like that, you may create a lot of beans in your system. So just use the easy way.

不需要像 那样创建 bean RedisTemplate< String, Long >,如果你这样做,你可能会在你的系统中创建很多 bean。所以只需使用简单的方法。

回答by tyrantqiao

Give something different, as now is 2018(something changes a lot which blocks me for a long time)

给出一些不同的东西,就像现在是 2018 年一样(变化很大,阻碍了我很长时间)

  • First Dependency(Gradle)

    compile('org.springframework.boot:spring-boot-starter-data-redis')
    compile('org.springframework.boot:spring-boot-starter-data-redis-reactive')
    
  • 第一Dependency(Gradle)

    compile('org.springframework.boot:spring-boot-starter-data-redis')
    compile('org.springframework.boot:spring-boot-starter-data-redis-reactive')
    

Remember to use the latest version, you can use gradle-use-latest-versions-plugin to check whether the dependency is latest.

记得使用最新版本,可以使用 gradle-use-latest-versions-plugin 来检查依赖是否是最新的。

  1. RedisServer

    [Linux] 
    redis-server
    
    [spring.properties]
    spring.redis.host=localhost
    spring.redis.port=6379
    spring.cache.cache-names=orderIdPool,users
    spring.cache.redis.cache-null-values=true
    spring.cache.redis.time-to-live=600000ms
    
  2. Redis config

    @Configuration
    public class RedisConfig {
    
    /**
     * create a lettuceConnectionFactory for redisTemplate {@link 
     #redisUserTemplate()}
     * @return LettuceConnectionFactory, the old version use Jedis
    */
    @Bean
    public LettuceConnectionFactory lettuceConnectionFactory() {
        return new LettuceConnectionFactory();
    }
    
    /**
     * Description: aiming to create a template for Long and user(To be a user cache)
     * @return redisTemplate<Long,User>
    */
    @Bean
    @Qualifier("redisUserTemplate")
    public RedisTemplate<Long, User> redisUserTemplate() {
        RedisTemplate<Long, User> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(new LettuceConnectionFactory());
        return redisTemplate;
    }
    
  3. use RedisTemplate

    private RedisTemplate redisTemplate
    //@Qualifier to choose the bean you actually want. 
    @Autowired
    public constructor(@Qualifier("xxxRedisTemplate")RedisTemplate redisTemplate){
      this.redisTemplate=redisTemplate;
    }
    
  4. use redisTemplate

    private HashOperations<Long, byte[], byte[]> hashOperations = redisUserTemplate.opsForHash();
    private HashMapper<Object, byte[], byte[]> hashMapper = new ObjectHashMapper();
    @Nullable
    public void saveObject(Long key, User user) {
       Map<byte[], byte[]> mappedHash = hashMapper.toHash(user);
       hashOperations.putAll(key, mappedHash);
    }
    public Object loadObject(Long key) {
       Map<byte[], byte[]> loadedHash = hashOperations.entries(key);
       return hashMapper.fromHash(loadedHash);
    }
    
  5. If you encounter the circular spring injection error, consider setter injection, @Lazy, @PostConstructor or implements ApplicationContextAware, InitalizingBean, for more information surf this link how to fix this

  1. Redis服务器

    [Linux] 
    redis-server
    
    [spring.properties]
    spring.redis.host=localhost
    spring.redis.port=6379
    spring.cache.cache-names=orderIdPool,users
    spring.cache.redis.cache-null-values=true
    spring.cache.redis.time-to-live=600000ms
    
  2. Redis 配置

    @Configuration
    public class RedisConfig {
    
    /**
     * create a lettuceConnectionFactory for redisTemplate {@link 
     #redisUserTemplate()}
     * @return LettuceConnectionFactory, the old version use Jedis
    */
    @Bean
    public LettuceConnectionFactory lettuceConnectionFactory() {
        return new LettuceConnectionFactory();
    }
    
    /**
     * Description: aiming to create a template for Long and user(To be a user cache)
     * @return redisTemplate<Long,User>
    */
    @Bean
    @Qualifier("redisUserTemplate")
    public RedisTemplate<Long, User> redisUserTemplate() {
        RedisTemplate<Long, User> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(new LettuceConnectionFactory());
        return redisTemplate;
    }
    
  3. 使用RedisTemplate

    private RedisTemplate redisTemplate
    //@Qualifier to choose the bean you actually want. 
    @Autowired
    public constructor(@Qualifier("xxxRedisTemplate")RedisTemplate redisTemplate){
      this.redisTemplate=redisTemplate;
    }
    
  4. 使用 redisTemplate

    private HashOperations<Long, byte[], byte[]> hashOperations = redisUserTemplate.opsForHash();
    private HashMapper<Object, byte[], byte[]> hashMapper = new ObjectHashMapper();
    @Nullable
    public void saveObject(Long key, User user) {
       Map<byte[], byte[]> mappedHash = hashMapper.toHash(user);
       hashOperations.putAll(key, mappedHash);
    }
    public Object loadObject(Long key) {
       Map<byte[], byte[]> loadedHash = hashOperations.entries(key);
       return hashMapper.fromHash(loadedHash);
    }
    
  5. 如果遇到循环 spring 注入错误,请考虑 setter 注入、@Lazy、@PostConstructor 或实现 ApplicationContextAware、InitalizingBean,有关更多信息,请浏览此链接如何解决此问题