V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Tianny
V2EX  ›  Java

Spring Boot 关于 @Autowired 和 @Resource 注解问题。

  •  
  •   Tianny · 2018-12-13 21:34:44 +08:00 · 3611 次点击
    这是一个创建于 2178 天前的主题,其中的信息可能已经有所发展或是发生改变。

    当我使用 @Resource 注解时候,@Value 注解的属性都无法从 application.properties 中正确读取值,值都为 null。而使用 @Autowired 的时候却可以获取正确的值。注意:当我 debug 打断点时,程序还没有走到 @Bean 注解的代码段,也就是说还没有创建 Bean。还有不管使用 @Resource 还是 @Autowired 注解都能成功的将创建的 Bean 注册到 IOC 容器中。只是使用 @Resource 注解时创建的 Bean 的属性值都为 null,也就是前面提到的 @Value 拿不到 application.properties 里的值。不知道为什么会出现这种情况?请各位指导一下。。

    Bean 的依赖关系如下:jedisUtil -> jedisWritePool -> jedisPoolConfig

    代码如下:

    package cc.tianny.o2o.config.redis;
    
    import cc.tianny.o2o.cache.JedisPoolWriper;
    import cc.tianny.o2o.cache.JedisUtil;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import redis.clients.jedis.JedisPoolConfig;
    
    import javax.annotation.Resource;
    
    /**
     * spring-redis 迁移配置
     */
    @Configuration
    public class RedisConfiguration {
        @Value("${redis.hostname}")
        private String hostname;
    
        @Value("${redis.port}")
        private int port;
    
        @Value("${redis.pool.maxActive}")
        private int maxTotal;
    
        @Value("${redis.pool.maxIdle}")
        private int maxIdle;
    
        @Value("${redis.pool.maxWait}")
        private long maxWaitMillis;
    
        @Value("${redis.pool.testOnBorrow}")
        private boolean testOnBorrow;
    
    //    @Resource(name = "jedisPoolConfig")
        @Autowired
        private JedisPoolConfig jedisPoolConfig;
    //    @Resource(name = "jedisWritePool")
        @Autowired
    private JedisPoolWriper jedisWritePool;
    //    @Resource(name = "jedisUtil")
        @Autowired
        private JedisUtil jedisUtil;
    
        /**
         * 创建 redis 连接池的相关配置
         *
         * @return
         */
        @Bean(name = "jedisPoolConfig")
        public JedisPoolConfig createJedisPoolConfig() {
            JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
            jedisPoolConfig.setMaxTotal(maxTotal);
            jedisPoolConfig.setMaxIdle(maxIdle);
            jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
            jedisPoolConfig.setTestOnBorrow(testOnBorrow);
            return jedisPoolConfig;
        }
    
        @Bean(name = "jedisWritePool")
        public JedisPoolWriper createJedisPoolWriper() {
            return new JedisPoolWriper(jedisPoolConfig, hostname, port);
        }
    
        /**
         * 创建 Redis 工具类,封装好 Redis 的连接以进行相关操作
         *
         * @return
         */
        @Bean(name = "jedisUtil")
        public JedisUtil createJedisUtil() {
            JedisUtil jedisUtil = new JedisUtil();
            jedisUtil.setJedisPool(jedisWritePool);
            return jedisUtil;
        }
    
        /**
         * Redis 的 key 操作
         *
         * @return
         */
        @Bean(name = "jedisKeys")
        public JedisUtil.Keys createJedisKeys() {
            return jedisUtil.new Keys();
        }
    
        /**
         * Redis 的 Strings 操作
         *
         * @return
         */
        @Bean(name = "jedisStrings")
        public JedisUtil.Strings createJedisStrings() {
            return jedisUtil.new Strings();
        }
    }
    
    
    8 条回复    2018-12-14 13:00:21 +08:00
    fmumu
        1
    fmumu  
       2018-12-13 23:55:04 +08:00   ❤️ 1
    可能需要 @PropertySource(value={"classpath:config.properties"})?
    Tianny
        3
    Tianny  
    OP
       2018-12-14 06:36:56 +08:00
    @fmumu 谢谢 试了下 没起效果
    alamaya
        4
    alamaya  
       2018-12-14 09:40:42 +08:00   ❤️ 1
    翻翻源码呗,肯定是 Autowired 的注入顺序和 Resource 的注入时机不一样,导致你用 Resource 注入的时候 property 根本还没注入进来,而你对 value 的依赖是写在代码里的,容器不可能分析你的依赖关系
    fffay
        5
    fffay  
       2018-12-14 09:46:01 +08:00   ❤️ 2
    @Value 和 @Resource 注解没什么关系的,AutowiredAnnotationBeanPostProcessor 你可以在这个类里面打个断点看看,不知道你有没有指定什么别的 ApplicationContext,一般 Spring boot 默认的都会注册 AutowiredAnnotationBeanPostProcessor 这个 bean 的,这个 processor 会处理对 @Value 和 @Autowired 的注入。如果解决了,麻烦说一下是什么原因造成的
    qiyuey
        6
    qiyuey  
       2018-12-14 10:43:11 +08:00   ❤️ 2
    @Configuration 内不需要使用 @Autowired,只需要将 [被依赖的 Bean 对象] 作为 [依赖方 @Bean 方法] 的入参即可
    Tianny
        7
    Tianny  
    OP
       2018-12-14 12:59:55 +08:00
    @qiyuey 是的。我用你的方法。将上面的 @Autowired 的注解去掉,是没有问题的。
    Tianny
        8
    Tianny  
    OP
       2018-12-14 13:00:21 +08:00
    @fay9395 暂时还不清楚。还要再研究下。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1009 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 19:40 · PVG 03:40 · LAX 11:40 · JFK 14:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.