是否可以将@Qualifier批注设置为Java类中的私有静态变量?

时间:2019-01-01 15:04:42

标签: java spring annotations

我目前正在使用JDBC模板从数据库中获取数据。为此,我创建了一个“静态”存储库类(即标记为“ final”的类,并带有一个私有构造函数)。在其中,我试图设置两个私有静态PlatformTransactionManager类变量的值。

但是,我的IntelliJ告诉我,类变量的值始终为null,我不知道如何解决此问题。

我希望将它们用作静态构造函数中的局部变量,因为我真正想要的是我将使用PTM准备的JdbcTemplate常量。由于我不知道该怎么做,因此我尝试将它们放入private static final字段中。但是IntelliJ也不允许这样做。

为了解决这个问题,我研究了以下线程:

。 。 。以及关于预选赛的注释:

重要说明:

  • 我正在处理的项目没有XML配置文件。项目中有[*] Config个文件可以处理配置。
  • 要注意的另一件事是,我一般不太了解注释(例如Java,C#等)。也就是说,我知道它们背后的基本思想,但是我不知道它们是如何工作的。 。 。而且我已经不记得很多Spring框架了(因为我已经从事Core Java和C#.NET相当一段时间了)。这样。 。 。感谢您为解决此问题提供的帮助。

以下是我的源代码的示例:

private final class Repository {

  private Repository() {}

  private static final JdbcTemplate TEMPLATE1;
  private static final JdbcTemplate TEMPLATE2;

  @Qualifier( "transactionManager1" )
  private static PlatformTransactionManager manager1;

  @Qualifier( "transactionManager2" )
  private static PlatformTransactionManager manager2;

  static {
    // NOTE: For this one, IntelliJ shows me an error stating, "Value 'manager1'
    // is always 'null'."
    DataSource source =
      ( ( JpaTransactionManager ) manager1 ).getDataSource();

    TEMPLATE1 = new JdbcTemplate( source );

    // NOTE: Here, there is no error ... at least, IntelliJ isn't showing any.
    source = ( ( JpaTransactionManager ) manager2 ).getDataSource();

    TEMPLATE2 = new JdbcTemplate( source );
  }

  public Map<String, Object> fetchData() {
    return TEMPLATE1.queryForList( "..." ); // TODO: something
  }

}

1 个答案:

答案 0 :(得分:0)

您可以实现ApplicationContextAware接口来获取上下文对象,并且使用此上下文对象,即使在静态上下文中也可以获取Bean。

public class ApplicationBeansProvider implments ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        this.applicationContext = applicationContext;
    }

    public static Object getBean(String beanName) {
        return applicationContext.getBean(beanName);
    }
}

然后在您的代码中可以执行类似的操作

private final class Repository {

  private Repository() {}

  private static final JdbcTemplate TEMPLATE;

  private static PlatformTransactionManager manager = ApplicationBeansProvider.getBean("transactionManager");


  static {
    DataSource source =
      ( ( JpaTransactionManager ) manager ).getDataSource();

    TEMPLATE = new JdbcTemplate( source );

  }

  public Map<String, Object> fetchData() {
    return TEMPLATE1.queryForList( "..." ); // TODO: something
  }

}