Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How autowired RedisTemplate<String,Long>

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

@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$1.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
like image 827
yo_nas Avatar asked Dec 17 '14 08:12

yo_nas


People also ask

Can we Autowire string in Spring?

The Spring framework enables automatic dependency injection. In other words, by declaring all the bean dependencies in a Spring configuration file, Spring container can autowire relationships between collaborating beans. This is called Spring bean autowiring.

Why we use@ Autowired annotation in Spring?

Spring @Autowired annotation is used for automatic dependency injection. Spring framework is built on dependency injection and we inject the class dependencies through spring bean configuration file.

What is@ Autowired Spring?

The @Autowired annotation provides more fine-grained control over where and how autowiring should be accomplished. The @Autowired annotation can be used to autowire bean on the setter method just like @Required annotation, constructor, a property or methods with arbitrary names and/or multiple arguments.

What is the use of@ Autowired annotation?

@Autowired annotation is optional for constructor based injection. Here, the person object from the container is passed to the constructor while creating the Customer object. The setter method will be called with the Person object at runtime by the container.


2 Answers

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

  • First 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.

  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

like image 179
tyrantqiao Avatar answered Oct 04 '22 01:10

tyrantqiao


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.

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.run E.g.

Object[] sources = {AppConfig.class};
ApplicationContext ctx = SpringApplication.run(sources, args);
like image 42
sol4me Avatar answered Oct 04 '22 03:10

sol4me