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

2018-12-13 21:34:44 +08:00
 Tianny

当我使用 @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();
    }
}

3605 次点击
所在节点    Java
8 条回复
fmumu
2018-12-13 23:55:04 +08:00
可能需要 @PropertySource(value={"classpath:config.properties"})?
fmumu
2018-12-13 23:57:01 +08:00
Tianny
2018-12-14 06:36:56 +08:00
@fmumu 谢谢 试了下 没起效果
alamaya
2018-12-14 09:40:42 +08:00
翻翻源码呗,肯定是 Autowired 的注入顺序和 Resource 的注入时机不一样,导致你用 Resource 注入的时候 property 根本还没注入进来,而你对 value 的依赖是写在代码里的,容器不可能分析你的依赖关系
fffay
2018-12-14 09:46:01 +08:00
@Value 和 @Resource 注解没什么关系的,AutowiredAnnotationBeanPostProcessor 你可以在这个类里面打个断点看看,不知道你有没有指定什么别的 ApplicationContext,一般 Spring boot 默认的都会注册 AutowiredAnnotationBeanPostProcessor 这个 bean 的,这个 processor 会处理对 @Value 和 @Autowired 的注入。如果解决了,麻烦说一下是什么原因造成的
qiyuey
2018-12-14 10:43:11 +08:00
@Configuration 内不需要使用 @Autowired,只需要将 [被依赖的 Bean 对象] 作为 [依赖方 @Bean 方法] 的入参即可
Tianny
2018-12-14 12:59:55 +08:00
@qiyuey 是的。我用你的方法。将上面的 @Autowired 的注解去掉,是没有问题的。
Tianny
2018-12-14 13:00:21 +08:00
@fay9395 暂时还不清楚。还要再研究下。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/517359

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX