【问题标题】:Error while creating Bean even though the Dependency Bean is there即使存在依赖项 Bean,创建 Bean 时也会出错
【发布时间】:2017-11-28 10:50:17
【问题描述】:

我的配置类有一些依赖 Beans

public class WebConfig{
    @Bean
        @Qualifier("geojedis")
        public StringRedisTemplate geoJedisTemplate(
                @Qualifier("geographyJedisConnectionFactory") final JedisConnectionFactory connectionFactory) {

            // Create a RedisTemplate implementation which is basically of string
            // data structure.
            StringRedisTemplate redisTemplate = new StringRedisTemplate(connectionFactory);

            return redisTemplate;
        }

    @Bean
        @Qualifier("capacityStringRedisTemplate")
        public StringRedisTemplate capacityStringRedisTemplate(
                @Qualifier("capacityJedisConnectionFactory") final JedisConnectionFactory connectionFactory) {

            // Create a RedisTemplate implementation which is basically of string
            // data structure.
            StringRedisTemplate redisTemplate = new StringRedisTemplate(connectionFactory);

            return redisTemplate;
        }

    @Bean
        public JedisConnectionFactory geographyJedisConnectionFactory() {
            JedisConnectionFactory connectionFactory = new JedisConnectionFactory();
            return connectionFactory;
        }

    @Bean
        public JedisConnectionFactory capacityJedisConnectionFactory() {
            JedisConnectionFactory connectionFactory = new JedisConnectionFactory();
            return connectionFactory;
        }
    }

但我收到以下错误。当我检查所有配置时,我还定义了Qualifier 以映射正确的依赖项。非常感谢任何帮助。

org.springframework.beans.factory.UnsatisfiedDependencyException: 在类路径中定义名称为“redisTemplate”的 bean 创建错误 资源 [org/springframework/boot/autoconfigure/redis/RedisAutoConfiguration$RedisConfiguration.class]: 通过构造函数参数表达的不满足的依赖关系 类型索引 0 [org.springframework.data.redis.connection.RedisConnectionFactory]: : 没有符合条件的 bean 类型 [org.springframework.data.redis.connection.RedisConnectionFactory] ​​是 已定义:预期的单个匹配 bean,但找到了 2: 地理JedisConnectionFactory,容量JedisConnectionFactory;嵌套的 例外是 org.springframework.beans.factory.NoUniqueBeanDefinitionException: 否 符合条件的 bean 类型 [org.springframework.data.redis.connection.RedisConnectionFactory] ​​是 已定义:预期的单个匹配 bean,但找到了 2: 地理JedisConnectionFactory,容量JedisConnectionFactory

【问题讨论】:

  • 实际上错误消息很清楚:预期的单个匹配 bean 但找到了 2. 使用 @Qualifier 的 bean 定义。
  • @Habil 我已经使用@Qualifier 定义了 Bean,即使它说没有找到匹配的 bean。同类型问题stackoverflow.com/questions/36621090/…
  • 试试这样的bean def; @Bean(name="bean1") public JedisConnectionFactory geographyJedisConnectionFactory() { JedisConnectionFactory connectionFactory = new JedisConnectionFactory();返回连接工厂; } @Bean(name="bean2") public JedisConnectionFactory capacityJedisConnectionFactory() { JedisConnectionFactory connectionFactory = new JedisConnectionFactory();返回连接工厂; }
  • 虽然 name() 属性可用,但确定 bean 名称的默认策略是使用 @Bean 方法的名称。这是方便和直观的,但如果需要显式命名,可以使用名称属性(或其别名值)。您能否解释一下需要明确设置@Bean("bean1") 以获得更多docs.spring.io/spring-framework/docs/current/javadoc-api/org/…

标签: java spring spring-boot


【解决方案1】:

如果 Spring Context 中没有默认的“redisTemplate”,则会在 RedisAutoConfiguration 中创建一个 bean。

@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(
        RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
    RedisTemplate<Object, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
}

这个需要一个RedisConnectionFactory,但找到了两个。

作为一种变通方法,您可以创建一个名为“redisTemplate”的虚拟 RedisTemplate 而不使用它。

由于它通过 bean 名称进行检查,因此只要没有尝试 @Autowire 它就足够了:

@Bean
public Object redisTemplate() {
    return new Object();
}

【讨论】:

  • 我刚刚将我的RedisTemplate&lt;String, String&gt; geoRedisTemplate 重命名为RedisTemplate&lt;String, String&gt; redisTemplate。现在它工作正常。谢谢@Yoory N
【解决方案2】:

您可以简单地调用连接工厂bean创建方法而不是注入:

    @Bean       
    public StringRedisTemplate capacityStringRedisTemplate() {

        // Create a RedisTemplate implementation which is basically of string
        // data structure.
        StringRedisTemplate redisTemplate = 
             new StringRedisTemplate(capacityJedisConnectionFactory());

        return redisTemplate;
    }

这将直接指向您正在寻找的那个

【讨论】:

  • 这是否注入了由 Spring 容器创建的同一个 bean?
  • @MaciejKowalski 但我们需要创建 JedisConnectionFactory Bean 并需要注入它,否则 afterPropertiesSet() 不会被调用,因此它不会从池中获取连接,而是会创建一个新的每次连接。
  • Spring documentation 展示了如何拦截@Bean 方法之间的跨方法调用,并使用缓存在容器中的 bean,而不是像我们通常期望的那样创建新实例。谢谢@Maciej Kowalski
【解决方案3】:

在配置类上方使用 @EnableAutoConfiguration(exclude = RedisAutoConfiguration.class) 并提供自定义连接属性

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-05
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 2017-09-24
    • 2016-12-09
    • 2018-01-10
    相关资源
    最近更新 更多