我正在设置Spring项目以使用Spring Security。
我想使用JDBC身份验证并连接到MySQL数据库。
我无法使用@Autowired
创建bean。
我用Gradle建立了我的春季项目。当我启动tomcat时,看到如下错误消息。
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)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:849)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:400)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:291)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4680)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5150)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1377)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1367)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:902)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:831)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1377)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1367)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:902)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:423)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:928)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.startup.Catalina.start(Catalina.java:634)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:350)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:492)
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
我已经创建了3个Java配置类,如下所示。
@Configuration
@EnableWebMvc
@Import(ThymeleafConfig.class)
@ComponentScan("(my top level package name).controller")
public class WebMvcConfig implements WebMvcConfigurer {
@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
return new RequestMappingHandlerMapping();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("static/**").addResourceLocations("classpath:/static/");
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("general/login");
}
}
WebSecurityConfig
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(10);
}
@Bean
public RequestMatcher logoutRequestMatcher() {
return new AntPathRequestMatcher("/logout");
}
@Autowired
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();
http.logout().logoutRequestMatcher(logoutRequestMatcher()).invalidateHttpSession(true).and()
.csrf();
}
}
数据源配置
@Configuration
@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/(my database name)?characterEncoding=UTF-8&serverTimezone=JST&useSSL=false");
basicDataSource.setUsername("(username)");
basicDataSource.setPassword("(password)");
return basicDataSource;
}
}
“人员”表
mysql> SHOW COLUMNS FROM personnel;
+-----------------------+-------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+-------------------------------+------+-----+---------+----------------+
| personnel_id | smallint(4) unsigned zerofill | NO | PRI | NULL | auto_increment |
| insrance_num | varchar(15) | YES | | NULL | |
| first_name | varchar(20) | NO | | NULL | |
| last_name | varchar(20) | NO | | NULL | |
| first_name_kana | varchar(20) | NO | | NULL | |
| last_name_kana | varchar(20) | NO | | NULL | |
| gender | char(1) | NO | | NULL | |
| birthday | date | NO | | NULL | |
| postal_code | char(8) | NO | | NULL | |
| address | varchar(100) | NO | | NULL | |
| entering_company_date | date | NO | | NULL | |
| mail_address | varchar(254) | NO | | NULL | |
| contract_type_id | smallint(3) unsigned zerofill | YES | MUL | NULL | |
| retiremented_flg | bit(1) | NO | | b'0' | |
| retirement_date | date | YES | | NULL | |
| next_holiday | date | YES | | NULL | |
| password | varchar(100) | NO | | NULL | |
+-----------------------+-------------------------------+------+-----+---------+----------------+
17 rows in set (0.08 sec)
build.gradle
plugins {
id 'java'
id 'eclipse'
id 'eclipse-wtp'
id 'war'
id "io.freefair.lombok" version "3.7.5"
}
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
repositories {
jcenter()
}
dependencies {
// spring framework
implementation "org.springframework:spring-context:${springVersion}"
implementation "org.springframework:spring-webmvc:${springVersion}"
implementation "org.springframework:spring-jdbc:${springVersion}"
implementation "org.springframework:spring-tx:${springVersion}"
implementation "org.springframework.security:spring-security-web:${springVersion}"
implementation "org.springframework.security:spring-security-config:${springVersion}"
//db
implementation "org.mybatis:mybatis:3.5.1"
implementation "org.mybatis:mybatis-spring:2.0.1"
implementation "mysql:mysql-connector-java:${jdbcVersion}"
implementation "org.apache.commons:commons-dbcp2:2.6.0"
//thymeleaf
implementation "org.thymeleaf:thymeleaf-spring5:${thymeleafSpringVersion}"
implementation "org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.0.4.RELEASE"
//Logger
implementation "org.slf4j:slf4j-api:${slf4jVersion}"
implementation "org.slf4j:slf4j-log4j12:${slf4jVersion}"
//others
implementation "javax.servlet:jstl:${jstlVersion}"
implementation "javax.validation:validation-api:${validationApiVersion}"
compileOnly "javax.servlet:javax.servlet-api:${servletApiVersion}"
}
group = 'xxx'
version = '1.0.0-BUILD-SNAPSHOT'
description = 'xxx'
sourceCompatibility = '1.11'
我希望已创建BasicDataSource对象,并查看登录页面。
答案 0 :(得分:1)
您的项目找不到datasourceBean,
更改
@ComponentScan("(my top level package name).controller")
以包含DataSourceConfig
类包
例如DataSourceConfig
位于软件包my.test.package.DataSourceConfig
至少ComponentScan
应该是
@ComponentScan(`my.test.package")