简体   繁体   English

Spring @Bean 名称,不适用于 @Qualifier

[英]Spring @Bean Name, is not working with @Qualifier

I have a spring boot application.我有一个 spring 启动应用程序。 It creates LocalSessionFactoryBean Object and inject into session factory variable.它创建 LocalSessionFactoryBean Object 并注入 session 工厂变量。 It works fine as follow:它工作正常,如下所示:

@Autowired
  @Qualifier(value="sessionFactory")
  private SessionFactory sessionFactory;


  @Primary
  @Bean
  public LocalSessionFactoryBean sessionFactory() {
    LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
    factory.setDataSource(dataSource);
    factory.setPackagesToScan(
        new String[] {
          "com.abc..entities",
          "com.abc.xyz.entities",
          "
        });
    factory.setHibernateProperties(hibernateProperties());
    return factory;
  }

However, I need to change bean Name of sessionFactory, which is default as function name, from sessionFactory to entityManagerFactory, so I did following:但是,我需要将 sessionFactory 的 bean 名称(默认为 function 名称)从 sessionFactory 更改为 entityManagerFactory,所以我做了以下操作:

  @Autowired
  @Qualifier(value="entityManagerFactory")
  private SessionFactory sessionFactory;


  @Primary
  @Bean(name="entityManagerFactory")
  public LocalSessionFactoryBean sessionFactory() {
    LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
    factory.setDataSource(dataSource);
    factory.setPackagesToScan(
        new String[] {
          "com.abc..entities",
          "com.abc.xyz.entities",
          "
        });
    factory.setHibernateProperties(hibernateProperties());
    return factory;
  }

But it throws error:但它会引发错误:

> Error creating bean with name 'XYZ': Unsatisfied dependency expressed
> through field 'sessionFactory'; nested exception is
> org.springframework.beans.factory.NoSuchBeanDefinitionException: No
> qualifying bean of type 'org.hibernate.SessionFactory' available:
> expected at least 1 bean which qualifies as autowire candidate.
> Dependency annotations:
> {@org.springframework.beans.factory.annotation.Autowired(required=true),
> @org.springframework.beans.factory.annotation.Qualifier(value=entityManagerFactory)}

I believe i did it correctly, what did I miss here?我相信我做得对,我在这里错过了什么?

Update:-更新:-

I tried following as mentioned in one of answer but it did not work:我尝试按照答案之一中提到的方法进行操作,但没有成功:

@Autowired
  @Qualifier(value = "entityManagerFactory")
  private SessionFactory sessionFactory; 

and changed method as并将方法更改为

@Primary
@Bean

public LocalSessionFactoryBean entityManagerFactory()
 { ..........},


>  Unsatisfied dependency expressed through field 'sessionFactory';
> nested exception is
> org.springframework.beans.factory.NoSuchBeanDefinitionException: No
> qualifying bean of type 'org.hibernate.SessionFactory' available:
> expected at least 1 bean which qualifies as autowire candidate.
> Dependency annotations:
> {@org.springframework.beans.factory.annotation.Autowired(required=true),
> @org.springframework.beans.factory.annotation.Qualifier(value=entityManagerFactory)}

What I think that happens here, is that entityManagerFactory is automatically registered from spring for another bean.我认为这里发生的是 entityManagerFactory 自动从 spring 注册另一个 bean。 Therefore you don't get what you ask for.因此,您没有得到您所要求的。

Try changing a little bit the name试着改一下名字

@Bean(name="customEntityManagerFactory")
  public LocalSessionFactoryBean sessionFactory() {

and then接着

@Autowired
  @Qualifier("customEntityManagerFactory")
  private SessionFactory sessionFactory;

So let me give a high overview of all this @Autowire @Qualifier @Component ...因此,让我对所有这些@Autowire @Qualifier @Component进行一个高度概述......

@Autowire : This is A great way of making the injection in Spring explicit. @Autowire :这是在 Spring 中进行显式注入的好方法。 But there are cases that Spring gets confused on which dependency to inject.但是有些情况下 Spring 对注入哪个依赖项感到困惑。

There comes the @Qualifier : You eliminate the ambiguity issue:) So even if Spring finds multiple beans to inject of the same type it knows which one to do so. @Qualifier出现了:您消除了歧义问题:) 因此,即使 Spring 找到要注入的多个相同类型的 bean,它也知道要注入哪一个。

But if you want to use your specific implementation you need to specify that implementation with the @Component so the qualifier name will be used.但是,如果您想使用您的特定实现,您需要使用@Component指定该实现,以便使用限定符名称。

@Component("fooFormatter")
public class FooFormatter implements Formatter {
 
    public String format() {
        return "foo";
    }
}

And then:接着:

public class FooService {
     
    @Autowired
    @Qualifier("fooFormatter")
    private Formatter formatter;
}

And there is another option as @Boug said in the above answer.正如@Boug 在上述答案中所说,还有另一种选择。 Where you @Autowire by name.您在哪里@Autowire按名称。 So the Spring will know that it must use the field name that is a match with the value of the @Component .因此 Spring 将知道它必须使用与@Component的值匹配的字段名称。

eg例如

public class FooService {
     
    @Autowired
    private Formatter fooFormatter;
}

I hope that all this makes sense:)我希望这一切都有意义:)

Here you can read more Check here在这里你可以阅读更多检查这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM