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
How autowired RedisTemplate<String,Long>
提问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.run
E.g.
获得配置文件后,您需要将其传递给SpringApplication.run
Eg
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 sol4me
said 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 来检查依赖是否是最新的。
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
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; }
use RedisTemplate
private RedisTemplate redisTemplate //@Qualifier to choose the bean you actually want. @Autowired public constructor(@Qualifier("xxxRedisTemplate")RedisTemplate redisTemplate){ this.redisTemplate=redisTemplate; }
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); }
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
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
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; }
使用RedisTemplate
private RedisTemplate redisTemplate //@Qualifier to choose the bean you actually want. @Autowired public constructor(@Qualifier("xxxRedisTemplate")RedisTemplate redisTemplate){ this.redisTemplate=redisTemplate; }
使用 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); }
如果遇到循环 spring 注入错误,请考虑 setter 注入、@Lazy、@PostConstructor 或实现 ApplicationContextAware、InitalizingBean,有关更多信息,请浏览此链接如何解决此问题