LoginSignup
1
0

More than 1 year has passed since last update.

SonarLintからRSPEC-3305のご指摘受けたのですぐ対応しちゃいましょう

Posted at

SonarLintのエラー

業務でコーディングしていたら、SonarLintが下記のご指摘をしてくれました。
Inject this field value directly into "sqlSessionFactory", the only method that uses it

エラー発生時のコード

一部抜粋です。

@Autowired
private ApplicationContext context;

@Bean(name = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(
    @Qualifier("datasource") DataSource dataSource) throws Exception {
  SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
  sqlSessionFactoryBean.setDataSource(dataSource);
  sqlSessionFactoryBean.setMapperLocations(
    new PathMatchingResourcePatternResolver().getResources("./*.xml")
  );
  sqlSessionFactoryBean.setConfigLocation(
    context.getResource(
      Optional.ofNullable(
        context.getEnvironment().getProperty("mybatis.config-location")
      ).orElse(StringUtils.EMPTY)
    )
  );
  return sqlSessionFactoryBean.getObject();
}

そもそもSonarLintとは?

SonarLintはSonarSource社が開発・運営する統合開発環境(IDE)向けの静的コード解析ツールです。
https://www.sonarsource.com/products/sonarqube/

SonerQubeを利用することで、おおよそ下記の観点でご自身のソースコード内を解析してくれて指摘してくれます。

  • バグがないか
  • 脆弱性を含むコードになっていないか
  • 保守性を下げていないか
  • 冗長でないか

エラー発生の原因

これはSonarの下記ルールに抵触しているためでした。
https://rules.sonarsource.com/java/tag/spring/RSPEC-3305

When @Autowired is used, dependencies need to be resolved when the class is instantiated, which may cause early initialization of beans or lead the context to look in places it shouldn’t to find the bean. To avoid this tricky issue and optimize the way the context loads, dependencies should be requested as late as possible. That means using parameter injection instead of field injection for dependencies that are only used in a single @Bean method.

直接原因は、@Autowiredでフィールド注入したクラスが、単一メソッド(今回だとsqlSessionFactory)でしか使われていない ためです。

それが好ましくないのは以下の理由からです。

  • @Autowiredを使用すると、クラスのインスタンス化時に依存関係を解決する必要がある。
  • Beanの早期初期化を引き起こしたり、Beanを見つけるためにコンテキストが本来探すべきでない場所まで探したりする可能性がある。
  • コンテキストのロード方法を最適化するためには、依存関係はできるだけ遅く要求されるべき。

修正後のコード

あるフィールド注入したクラスが単一メソッドでしか利用されていない場合は、コンテキストのロード方法の最適化のために、@Autowiredでフィールド注入するのではなく、メソッドの引数に設定するのが好ましいということですので、そのように修正しました。

@Bean(name = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(
    @Qualifier("datasource") DataSource dataSource, ApplicationContext context) throws Exception {
    /** 以降は修正前と同一コードのため省略 */
}

以上です!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0