精华内容
下载资源
问答
  • 本文转自 ... 今天看到Spring操作redis 是可以将redisTemplate注入ValueOperations,避免了ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();...

    本文转自 https://www.cnblogs.com/tangyuanyuan/p/8067923.html

    今天看到Spring操作redis  是可以将redisTemplate注入到ValueOperations,避免了ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue(); 这样来获取ValueOperations;

    @Resource(name = "redisTemplate")
    private ValueOperations<String, Object> vOps;

    redisTemplate并不是ValueOperations的实现类,这两个在继承上毫无联系的两个类是如何注入的呢。

    后来查doGetBean()的代码才发现有一段以前没有详细的去看。

    复制代码

            // Check if required type matches the type of the actual bean instance.
            if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
                try {
                    return getTypeConverter().convertIfNecessary(bean, requiredType);
                }
                catch (TypeMismatchException ex) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Failed to convert bean '" + name + "' to required type '" +
                                ClassUtils.getQualifiedName(requiredType) + "'", ex);
                    }
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                }
            }

    复制代码

    如果你要实例化的对象和你的引用对象并不是同一种类型,也就是如redisTemplate和ValueOperations一般不是父子关系或接口实现关系,那么spring就会进行转换。

    用什么转换呢?Spring的editor。

    复制代码

    String editorName = targetType.getName() + "Editor";
            try {
                Class<?> editorClass = cl.loadClass(editorName);
                if (!PropertyEditor.class.isAssignableFrom(editorClass)) {
                    if (logger.isWarnEnabled()) {
                        logger.warn("Editor class [" + editorName +
                                "] does not implement [java.beans.PropertyEditor] interface");
                    }
                    unknownEditorTypes.add(targetType);
                    return null;
                }
                return (PropertyEditor) instantiateClass(editorClass);
            }

    复制代码

    spring会去加载 ValueOperations+Editor,即ValueOperationsEditor的类。且此类必须要实现PropertyEditor接口。

    而我们在ValueOperations的包目录下确实会找到ValueOperationsEditor。

    复制代码

    class ValueOperationsEditor extends PropertyEditorSupport {
    
        public void setValue(Object value) {
            if (value instanceof RedisOperations) {
                super.setValue(((RedisOperations) value).opsForValue());
            } else {
                throw new java.lang.IllegalArgumentException("Editor supports only conversion of type " + RedisOperations.class);
            }
        }
    }

    复制代码

    这个类非常简单,它重写了setValue方法,将redisTemplate中的opsForValue()返回值set进去,而opsForValue()返回值就是继承了ValueOperations的DefaultValueOperations。

    这样我们用editor get value的时候就能获取到DefaultValueOperations了。就可以将DefaultValueOperations注入到ValueOperations中去了。

     

    做个实验,写两个类

     

    复制代码

    public class ClassA {
        private String msg;
        public ClassA(String msg){
            this.msg=msg;
        }
        public void hi(){
            System.out.println(msg);
        }
    }

    复制代码

     

    @Component
    public class ClassB {
        public ClassA getA(){
            return new ClassA("this is A from B");
        }
    }

    类B有个方法可以获取A类实例,我们将此注入到A对象中。

    复制代码

    public class EditorTest extends BaseJunitTest{
        
        @Resource(name="classB")
        private ClassA a; 
        
        @Test   
        public void test(){
            a.hi();
        }
    }

    复制代码

    BaseJunitTest配置了一些spring的XML配置文件 不需要管它。
    此时我们还需要写一个ClassAEditor类。如果没有editor类的话当然会注入不了 并抛出一个异常
    Bean named 'classB' is expected to be of type 'xxx.test.ClassA' but was actually of type 'xxx.test.ClassB'
    我们完成ClassAEditor
    
    public class ClassAEditor extends PropertyEditorSupport{
          public void setValue(Object value) {
              super.setValue(((ClassB)value).getA());
          }
    }
     

    判断略去不写。

    运行程序,得到正确结果

     

    非常有意思的一个细节,工厂模式的一种体现。

    展开全文
  • REDISTEMPLATE如何注入VALUEOPERATIONS

    千次阅读 2018-06-20 14:31:38
    今天看到Spring操作redis 是可以将redisTemplate注入ValueOperations,避免了ValueOperations&lt;String, Object&gt; valueOperations = redisTemplate.opsForValue(); 这样来获取ValueOperations;@...

    今天看到Spring操作redis  是可以将redisTemplate注入到ValueOperations,避免了ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue(); 这样来获取ValueOperations;

    @Resource(name = "redisTemplate")
    private ValueOperations<String, Object> vOps;

    redisTemplate并不是ValueOperations的实现类,这两个在继承上毫无联系的两个类是如何注入的呢。

    后来查doGetBean()的代码才发现有一段以前没有详细的去看。

    复制代码
            // Check if required type matches the type of the actual bean instance.
            if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
                try {
                    return getTypeConverter().convertIfNecessary(bean, requiredType);
                }
                catch (TypeMismatchException ex) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Failed to convert bean '" + name + "' to required type '" +
                                ClassUtils.getQualifiedName(requiredType) + "'", ex);
                    }
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                }
            }
    复制代码

    如果你要实例化的对象和你的引用对象并不是同一种类型,也就是如redisTemplate和ValueOperations一般不是父子关系或接口实现关系,那么spring就会进行转换。

    用什么转换呢?Spring的editor。

    复制代码
    String editorName = targetType.getName() + "Editor";
            try {
                Class<?> editorClass = cl.loadClass(editorName);
                if (!PropertyEditor.class.isAssignableFrom(editorClass)) {
                    if (logger.isWarnEnabled()) {
                        logger.warn("Editor class [" + editorName +
                                "] does not implement [java.beans.PropertyEditor] interface");
                    }
                    unknownEditorTypes.add(targetType);
                    return null;
                }
                return (PropertyEditor) instantiateClass(editorClass);
            }
    复制代码

    spring会去加载 ValueOperations+Editor,即ValueOperationsEditor的类。且此类必须要实现PropertyEditor接口。

    而我们在ValueOperations的包目录下确实会找到ValueOperationsEditor。

    复制代码
    class ValueOperationsEditor extends PropertyEditorSupport {
    
        public void setValue(Object value) {
            if (value instanceof RedisOperations) {
                super.setValue(((RedisOperations) value).opsForValue());
            } else {
                throw new java.lang.IllegalArgumentException("Editor supports only conversion of type " + RedisOperations.class);
            }
        }
    }
    复制代码

    这个类非常简单,它重写了setValue方法,将redisTemplate中的opsForValue()返回值set进去,而opsForValue()返回值就是继承了ValueOperations的DefaultValueOperations。

    这样我们用editor get value的时候就能获取到DefaultValueOperations了。就可以将DefaultValueOperations注入到ValueOperations中去了。

     

    做个实验,写两个类

     

    复制代码
    public class ClassA {
        private String msg;
        public ClassA(String msg){
            this.msg=msg;
        }
        public void hi(){
            System.out.println(msg);
        }
    }
    复制代码

     

    @Component
    public class ClassB {
        public ClassA getA(){
            return new ClassA("this is A from B");
        }
    }

    类B有个方法可以获取A类实例,我们将此注入到A对象中。

    复制代码
    public class EditorTest extends BaseJunitTest{
        
        @Resource(name="classB")
        private ClassA a; 
        
        @Test   
        public void test(){
            a.hi();
        }
    }
    复制代码
    BaseJunitTest配置了一些spring的XML配置文件 不需要管它。
    此时我们还需要写一个ClassAEditor类。如果没有editor类的话当然会注入不了 并抛出一个异常
    Bean named 'classB' is expected to be of type 'xxx.test.ClassA' but was actually of type 'xxx.test.ClassB'
    我们完成ClassAEditor
    
    public class ClassAEditor extends PropertyEditorSupport{
          public void setValue(Object value) {
              super.setValue(((ClassB)value).getA());
          }
    }
    
    

    判断略去不写。

    运行程序,得到正确结果

     

    非常有意思的一个细节,工厂模式的一种体现。

    展开全文
  • 在主启动类中添加 @Bean(na me=...public ValueOperations valueOperations(){ RedisConnectionFactoryRedisConnectionFactory = newRedisConnectionFactory(); RedisTemplate redistemplate = new R...

    在主启动类中添加

    @Bean(na me="valueOperations")

    public ValueOperations valueOperations(){

    RedisConnectionFactory  RedisConnectionFactory = new RedisConnectionFactory();

    RedisTemplate redistemplate = new RedisTemplate();

    redisTemplate.setConnectionFactory(RedisConnectionFactory);

    ValueOperations valueOperations =redisTemplate.opsForValue();

    return valueOperation;

    }

    在serviceImpl实现类中注入

    @Resoure(name="redisTemplate")

    public ValueOperations valueOperations

    1. 想要在spring boot中使用redis,只要在pom文件中增加如下的配置就可以了。
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>```
    
    2. 引入spring-boot-redis jar包之后,选择相应的客户端配置连接就可以使用redis了,推荐使用Jedis。
    ```@Bean
    JedisConnectionFactory connectionFactory() {
        return new JedisConnectionFactory();
    }```
    
    3. 配置完连接后,就可以使用redis进行简单的存取了。如果存取的key,value都是String的,可以使用
    RedisTemplate<String, String>对象,该对象由spring boot自动扫描生成,在需要的地方可以直接注入。如果只是进行简单的存储,还可以生成
    ValueOperations对象来方便操作。
    ```@Bean
    ValueOperations<String, String> strOperations(RedisTemplate<String, String> redisTemplate) {
        return redisTemplate.opsForValue();
    }```
    
    4. 如果想要存取其他类型的对象,例如存取key为string,value为Integer类型的对象,可以new这个对象,然后配置连接即可使用。
    ```@Bean
    RedisTemplate<String, Integer> intRedisTemplate(JedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Integer> redisTemplate = new RedisTemplate<String, Integer>();
        redisTemplate.setConnectionFactory(connectionFactory);
        return redisTemplate;
    }```
    
    5. RedisTemplate对象默认使用jdkSerializer实现序列化,如果想要更换序列化的实现方式,例如使用json实现value的序列化,可以进行如下配置
    
    ```@Bean
    Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer(ObjectMapper objectMapper) {
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
                Object.class);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        return jackson2JsonRedisSerializer;
    }
    
    @Bean
    RedisTemplate<String, Object> objRedisTemplate(JedisConnectionFactory connectionFactory,
            Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        redisTemplate.setConnectionFactory(connectionFactory);
        redisTemplate.setDefaultSerializer(jackson2JsonRedisSerializer);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        return redisTemplate;
    }
    

    最后附上上述操作的完整代码

    @Configuration
    public class RedisConfig {
    
        @Bean
        JedisConnectionFactory connectionFactory() {
            return new JedisConnectionFactory();
        }
    
        @Bean
        ValueOperations<String, String> strOperations(RedisTemplate<String, String> redisTemplate) {
            return redisTemplate.opsForValue();
        }
    
        @Bean
        RedisTemplate<String, Integer> intRedisTemplate(JedisConnectionFactory connectionFactory) {
            RedisTemplate<String, Integer> redisTemplate = new RedisTemplate<String, Integer>();
            redisTemplate.setConnectionFactory(connectionFactory);
            return redisTemplate;
        }
    
        @Bean
        ValueOperations<String, Integer> intOperations(RedisTemplate<String, Integer> redisTemplate) {
            return redisTemplate.opsForValue();
        }
    
        @Bean
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer(ObjectMapper objectMapper) {
            Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
                    Object.class);
            jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
            return jackson2JsonRedisSerializer;
        }
    
        @Bean
        RedisTemplate<String, Object> objRedisTemplate(JedisConnectionFactory connectionFactory,
                Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer) {
            RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
            redisTemplate.setConnectionFactory(connectionFactory);
            redisTemplate.setDefaultSerializer(jackson2JsonRedisSerializer);
            StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
            redisTemplate.setKeySerializer(stringRedisSerializer);
            redisTemplate.setHashKeySerializer(stringRedisSerializer);
            return redisTemplate;
        }
    
        @Bean
        ValueOperations<String, Object> objOperations(RedisTemplate<String, Object> redisTemplate) {
            return redisTemplate.opsForValue();
        }
    
    }```
    
    参考文档:
    1.  http://docs.spring.io/spring-data/redis/docs/current/reference/html/
    2.  http://docs.spring.io/spring-framework/docs/4.0.4.RELEASE/javadoc-api/org/springframework/context/annotation/Configuration.html
    3. http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springf

     

    展开全文
  • 今天看到Spring操作redis 是可以将redisTemplate注入ValueOperations,避免了ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue(); 这样来获取ValueOperations; @Resource...

     

    今天看到Spring操作redis  是可以将redisTemplate注入到ValueOperations,避免了ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue(); 这样来获取ValueOperations;

    @Resource(name = "redisTemplate")
    private ValueOperations<String, Object> vOps;

    redisTemplate并不是ValueOperations的实现类,这两个在继承上毫无联系的两个类是如何注入的呢。

    后来查doGetBean()的代码才发现有一段以前没有详细的去看。

            // Check if required type matches the type of the actual bean instance.
            if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
                try {
                    return getTypeConverter().convertIfNecessary(bean, requiredType);
                }
                catch (TypeMismatchException ex) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Failed to convert bean '" + name + "' to required type '" +
                                ClassUtils.getQualifiedName(requiredType) + "'", ex);
                    }
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                }
            }

    如果你要实例化的对象和你的引用对象并不是同一种类型,也就是如redisTemplate和ValueOperations一般不是父子关系或接口实现关系,那么spring就会进行转换。

    用什么转换呢?Spring的editor。

    String editorName = targetType.getName() + "Editor";
            try {
                Class<?> editorClass = cl.loadClass(editorName);
                if (!PropertyEditor.class.isAssignableFrom(editorClass)) {
                    if (logger.isWarnEnabled()) {
                        logger.warn("Editor class [" + editorName +
                                "] does not implement [java.beans.PropertyEditor] interface");
                    }
                    unknownEditorTypes.add(targetType);
                    return null;
                }
                return (PropertyEditor) instantiateClass(editorClass);
            }

    spring会去加载 ValueOperations+Editor,即ValueOperationsEditor的类。且此类必须要实现PropertyEditor接口。

    而我们在ValueOperations的包目录下确实会找到ValueOperationsEditor。

    class ValueOperationsEditor extends PropertyEditorSupport {
    
        public void setValue(Object value) {
            if (value instanceof RedisOperations) {
                super.setValue(((RedisOperations) value).opsForValue());
            } else {
                throw new java.lang.IllegalArgumentException("Editor supports only conversion of type " + RedisOperations.class);
            }
        }
    }

    这个类非常简单,它重写了setValue方法,将redisTemplate中的opsForValue()返回值set进去,而opsForValue()返回值就是继承了ValueOperations的DefaultValueOperations。

    这样我们用editor get value的时候就能获取到DefaultValueOperations了。就可以将DefaultValueOperations注入到ValueOperations中去了。

     

    做个实验,写两个类

     

    public class ClassA {
        private String msg;
        public ClassA(String msg){
            this.msg=msg;
        }
        public void hi(){
            System.out.println(msg);
        }
    }

     

    @Component
    public class ClassB {
        public ClassA getA(){
            return new ClassA("this is A from B");
        }
    }

    类B有个方法可以获取A类实例,我们将此注入到A对象中。

    public class EditorTest extends BaseJunitTest{
        
        @Resource(name="classB")
        private ClassA a; 
        
        @Test   
        public void test(){
            a.hi();
        }
    }
    BaseJunitTest配置了一些spring的XML配置文件 不需要管它。
    此时我们还需要写一个ClassAEditor类。如果没有editor类的话当然会注入不了 并抛出一个异常
    Bean named 'classB' is expected to be of type 'xxx.test.ClassA' but was actually of type 'xxx.test.ClassB'
    我们完成ClassAEditor
    public class ClassAEditor extends PropertyEditorSupport{
          public void setValue(Object value) {
              super.setValue(((ClassB)value).getA());
          }
    }
     
     

    判断略去不写。

    运行程序,得到正确结果

     

    非常有意思的一个细节,工厂模式的一种体现。

     

     

    转载于:https://www.cnblogs.com/tangyuanyuan/p/8067923.html

    展开全文
  • 请看https://www.cnblogs.com/tangyuanyuan/p/8067923.html
  • 依赖注入(Dependency injection)是Spring容器的核心功能。Bean可以几种方式来声明自己的依赖: 构造方法参数、工厂方法参数、Setter属性;容器在构造、初始化bean的过程中,将适当的bean引用注入进去。 本章的内容...
  • spring boot redis RedisTemplate和ValueOperations对 string-value的操作  参照redisdoc文档的方法进行 打造 http://redisdoc.com/ 与文档中string对应 写出通用接口 与实现类  完整demo连接  //配置缓存 ...
  • 我这里已经将对应类型都获取了,都没问题,但是在valueOperations.decrement这里就出错,可我也序列化过了啊
  • 问题: 自动注入的RedisTemplate为空,报null指针 解决办法: 将RedisUtil注册为bean 再通过注入到要使用的地方
  • 使用Jwt做权限验证,生成的token存入redis,创建一个拦截器,拦截请求,在拦截器里对请求的token进行验证,当在拦截器里使用个人创建的一个redisUtil bean时,无法自动注入redisUtil bean,redisUtil 为null。...
  • 我有如下代码.RedisTemplate stringRedisTemplatedef accessRedis(){val = stringRedisTemplate.opsForValue().get('Key')}在我的控制器测试中,我打算注入一个模拟的RedisTemplate,它返回一个模拟的ValueOperations....
  • 文章目录报错内容错误原因解决办法手动...使用@Autowired注入RedisTemplate的时候,项目启动报错 Field redisTemplate in com.**.***.*** required a bean of type 'org.springframework.data.redis.core.RedisTempl...
  • 在oauth2的资源服务器上,想要获取redis中的clientId进行校验,但是redis工具类无法注入,redisTemplate一直为null,原因是AuthenticaitonManager先于redisTemplate加载,所以一直获取不到,不能注入,什么时候调用...
  • 最近在做微服务间用户权限打通的时候,由于当初设计的问题,用户的信息没有存在Redis中,而是由请求头携带的,因此需要在用户首次访问的时候缓存用户信息到Redis中,但是redisTemplate却无法注入到拦截其中,核心...
  • 关于 @Resource(name = “redisTemplate”) 为何可以为 ValueOperations 类型注入实体 @Autowired private RedisTemplate redisTemplate; @Resource(name = "redisTemplate") private ValueOperations, String> ...
  • 将配置文件的属性注入静态变量中 1.读取xml配置文件属性 @Component public class UrlBean { private static String fatpApiUrl; public static String getFatpApiUrl() { return fatpApiUrl; } //读取xml配置...
  • 由于工具类是 静态的方法,并且也不是 controller,不能直接使用注解注入 所以 RedisService 的注入方式如下:   public static RedisService redisService ; @Autowired public void setRedisService...
  • //RedisTemplate@5ec6a1b6 } 惊奇一:Spring容器内出现了多个类型一样的Bean,但Autowaired竟然成功了(这个绝提原因,读者可以去了解一下Spring4开始的泛型依赖注入,Spring在这方面有处理) 惊奇二:Spring自动...
  • A、测试注入不同类型的模板根据 @Resource 注解 import java.util.Set; import javax.annotation.Resource; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis....
  • import org.springframework.data.redis.core.ValueOperations; import java.util.Collections; import java.util.List; import java.util.Objects; public class RedisTest { public static void main(String[] ...
  • ValueOperations, String> opv = stringRedisTemplate.opsForValue(); // [key:value] [PISEN-CLOUD-LUNA-SECURITY-CODE-TEN-GLOBAL:099 : 次数] String str1 = opv.increment(TEN_CODE_GLOBAL_KEY_IN_REDIS +...
  • 最近看redis教程过程中,发现了直接将redisTemplate注入ValueOperations,进行两个无关联类之间的注入的方式,甚是不解,遂百度。 @Resource(name = "redisTemplate") private ValueOperatio...
  • private ValueOperations&amp;lt;K, V&amp;gt; valueOps; private ListOperations&amp;lt;K, V&amp;gt; listOps; private SetOperations&amp;lt;K, V&amp;gt; setOps; private ZSet...
  • 使用注解给类的属性注入参数

    千次阅读 2016-08-25 15:06:03
    ValueOperations, String> strOps; @Resource ( name = "redisTemplate" ) private ValueOperations, T> valOps; @Resource ( name = "redisTemplate" ) private ListOperations, T> listOps; ...
  • springboot中 使用 @Autowired 注入时, 是可以为静态变量进行注入的 package com.iwhere.footmark.tools; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data...
  • 而且不但可以将 RedisTemplate 注入到 ListOperations ,也可以注入ValueOperations、SetOperations、ZSetOperations、HashOperations 等类型上。 PropertyEditor Spring 框架可以通过 java.beans.PropertyEditor...
  • SpringBoot中注入RedisTemplate实例异常解决

    万次阅读 多人点赞 2018-08-10 18:36:03
    现在好像明白了,刚才的RedisTemplate, Object>注入时用到了@Autowired,@Autowired默认按照类型装配的。也就是说,想要获取RedisTemplate, Object>的Bean,要根据名字装配。那么自然想到使用@Resource,它默认按照...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,454
精华内容 581
关键字:

注入valueoperations