无法在 Spring Boot 项目中自动装配数据源

Posted

技术标签:

【中文标题】无法在 Spring Boot 项目中自动装配数据源【英文标题】:Cannot Autowire DataSource in Spring Boot Project 【发布时间】:2018-11-01 20:36:30 【问题描述】:

我正在尝试构建一个简单的 Spring Boot CRUD 应用程序,该应用程序还具有登录和注册选项以及 Spring Boot 安全性。我已经在使用 mysql 数据库,它可以很好地为我的应用程序保存数据。

问题是,在尝试创建我的 jdbcAuthentication 时,在我的 securityConfig 类中,它说我无法自动装配数据源,并且没有找到“数据源”类型的 bean(再次,我已经成功使用了我的 MySQL 数据库对于这个项目,暂时)。当我输入它时,它还会自动导入 javax.sql.DataSource 导入,因此它确实可以识别它。

我尝试搜索类似的问题,但无法正常工作。

这是我的代码:

Test2Application.java

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Test2Application 

public static void main(String[] args) 
    SpringApplication.run(Test2Application.class, args);


SecurityConfig.java

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.sql.DataSource;

@EnableWebSecurity
@RequestMapping("cheese")
public class SecurityConfig extends WebSecurityConfigurerAdapter 

    @Autowired
    private DataSource dataSource;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth.jdbcAuthentication().dataSource(dataSource)
                .usersByUsernameQuery("select email as principal, password as credentials, true from user where email=?");
    

    @Override
    protected void configure(HttpSecurity http) throws Exception
        http
                .authorizeRequests()
                .antMatchers(
                        "/cheese/index",
                        "/cheese/",
                        "/**/webjars/**",
                        "/cheese/signup",
                        "/cheese/login",
                        "/cheese/account",
                        "/cheese/add",
                        "/cheese/remove",
                        "/cheese/success").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().loginPage("/cheese/login")
                .permitAll();

       http.csrf().disable();
    

UserController.java

package com.example.demo.controllers;

import com.example.demo.models.Customer;
import com.example.demo.models.data.CustomerDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("cheese")
public class UserController 

    @Autowired
    private CustomerDao customerDao;

    @RequestMapping(value = "login")
    public String loginPage(Model model) 
        model.addAttribute("title", "Login Page");
        return "cheese/login";
    

    @RequestMapping(value = "account")
    public String accountInfo(Model model) 
        model.addAttribute("title", "Account Page");
        return "cheese/account";
    

    @GetMapping("signup")
    public String displaySignUpForm(Model model) 
        model.addAttribute("title", "Sign Up");
        model.addAttribute("customer", new Customer());
        return "cheese/signup";
    

    @PostMapping(value = "signup")
    public String processSignUp(Model model, @ModelAttribute Customer customer, Errors errors) 

        if (errors.hasErrors()) 
            return "cheese/signup";
        

        customerDao.save(customer);
        return "cheese/success";
    

Application.Properties

spring.datasource.url=jdbc:mysql://localhost:8889/******?useSSL=false
spring.datasource.username=****
spring.datasource.password=******

spring.jpa.database=MYSQL

spring.jpa.hibernate.ddl-auto = update

spring.jpa.show-sql=false

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

Pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>test2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>test2</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
        </dependency>

        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
        </dependency>

        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

【问题讨论】:

【参考方案1】:

Spring Security 配置应与Configuration 注释一起应用。 从SecurityConfig 中删除@RequestMapping("cheese")

正确的配置:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter 

【讨论】:

您好,感谢您的回答。我进行了更改,不幸的是遇到了同样的错误(即没有找到“DataSource”类型的 bean)。 以调试模式运行应用程序并检查自动配置报告。可以分享application.properties 文件的位置吗?【参考方案2】:

除了@Configuration 注释,添加@EnableAutoConfiguration 将尝试和配置代码。

    @Configuration
    @EnableAutoConfiguration
    public class SecurityConfig extends WebSecurityConfigurerAdapter 

此外,之后重建您的源代码。

【讨论】:

@SpringBootApplication注解可以用来启用这三个功能,即:@EnableAutoConfiguration:启用Spring Boot的自动配置机制@ComponentScan:启用@Component对应用所在包的扫描位于(参见最佳实践)@Configuration:允许在上下文中注册额外的 bean 或导入额外的配置类 @AntonNovopashin 嘿,是的,我知道。但这是在配置类中,而不是在主类中。此类不需要@SpringBootApplication,因为不需要像@ComponentScan 这样的其他注释。

以上是关于无法在 Spring Boot 项目中自动装配数据源的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Spring Boot 的组件类中自动装配推土机 Mapper

Spring Boot 2 实践记录之 条件装配

无法在 Spring Boot 2.0.0 中自动装配身份验证管理器

Spring-boot,无法自动装配类。未找到默认构造函数引发异常

通过注解实现自定义Spring Boot Starter自动装配

spring boot自动装配原理