質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.23%

【Spring・DBCP2】(内容変更)BasicDataSourceが@Autowiredでインスタンス化できていない

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 189
退会済みユーザー

退会済みユーザー

前提・実現したいこと

Spring Securityで、テーブルの登録内容を利用してログインできるようにしたい。

発生している問題・エラーメッセージ

Tomcatの起動時に下記のエラーが発生しています。
なお、IDEはeclipseで、Tomcatはeclipseに登録したものを起動しています。

※(6/29追記)はじめは、MyBatis-Springの@MapperScanが正常動作していないと考え投稿した質問だったのですが、それ以前の、BasicDataSourceを@Autowiredでインスタンス化する段階でエラーになっていることがわかりました。
そのため、内容を全面的に変更させていただきます。

なお、エラーメッセージを全て掲載しようとしたところ文字数オーバーとなってしまったため、スタックトレースを一部省略させていただきました。ご容赦ください。

ERROR: org.springframework.web.context.ContextLoader - Context initialization failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through field 'dataSource'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.apache.commons.dbcp2.BasicDataSource' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1411)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
    ... 40 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.apache.commons.dbcp2.BasicDataSource' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1654)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1213)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1167)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593)
    ... 45 more

該当のソースコード

下記のような構成です。

  • DataSourceの設定クラス:test.spring.config.DataSourceConfig
  • Spring Securityの設定クラス:test.spring.config.WebSecurityConfig
  • 社員情報テーブル 

DataSourceConfig

package spring.test.config;

import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.mybatis.spring.annotation.MapperScan;

@Configuration
@MapperScan("org.step.kintai.mapper")
@EnableTransactionManagement

public class DataSourceConfig {
  @Bean
  public BasicDataSource dataSource() {
    BasicDataSource basicDataSource = new BasicDataSource();
    basicDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    basicDataSource.setUrl(
        "jdbc:mysql://localhost:3306/holiday?characterEncoding=UTF-8&serverTimezone=JST&useSSL=false");
    basicDataSource.setUsername("admin01");
    basicDataSource.setPassword("Step2911");
    return basicDataSource;
  }
}

WebSecurityConfig 

package spring.test.config;

import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Bean
  public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder(10);
  }

  @Bean
  public RequestMatcher logoutRequestMatcher() {
    return new AntPathRequestMatcher("/logout");
  }

  @Autowired
  private BasicDataSource dataSource;

  @Autowired
  public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.jdbcAuthentication().dataSource(dataSource)
        .authoritiesByUsernameQuery(
            "select mail_address as username, 'USER' as authority from personnel "
                + " where personnel_id = ?")
        .usersByUsernameQuery(
            "select mail_address as username, password, true as enabled from personnel "
                + " where personnel_id = ?")
        .passwordEncoder(passwordEncoder());
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().antMatchers("/login", "/logout").permitAll().anyRequest()
        .authenticated();
    http.formLogin().loginPage("/login");
    http.logout().logoutRequestMatcher(logoutRequestMatcher()).invalidateHttpSession(true).and()
        .csrf();
  }
}

personnelテーブル(必要なカラムのみ)

mysql> SHOW COLUMNS FROM personnel;

Field Type Null Key Default Extra
 personnel_id            smallint(4) unsigned zerofill   NO     PRI   NULL      auto_increment 
 mail_address            varchar(254)                    NO           NULL                     
 password                varchar(100)                    NO           NULL                     

17 rows in set (0.08 sec)

試したこと

エラーメッセージから、

  • WebSecurityConfigクラスインスタンスが生成できていない
  • BasicDataSourceクラスのBean定義が出来ていない

ことは分かったのですが、その原因や対処法が全く分かりませんでした。
こちらでは上記のソースコード・テーブル定義の情報で十分であると考えましたが、上記以外に必要なものなどありましたらご指摘ください。

補足情報(FW/ツールのバージョンなど)

JDK: OpenJDK 11.0.2
Spring Framework 5.1.5.RELEASE
アプリケーションサーバ:Tomcat 9.0.17
RDBMS: MySQL 8.0.16

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

-1

なかなか回答が頂けなかったため、他所で質問して解決しました。

WebSecurityConfigクラスに"@ComponentScan("spring.test")"の記載がなかったため、DataSourceConfigクラスをConfigurationクラスとして認識出来ていなかったようです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.23%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる