【问题标题】:Spring Boot @Mapper Bean creation issue : Application Failed to start. Error : Consider defining a bean of TypeSpring Boot @Mapper Bean 创建问题:应用程序无法启动。错误:考虑定义一个 bean 类型
【发布时间】:2021-01-18 19:34:12
【问题描述】:

我是 spring 新手,当我尝试执行我的项目的 mvn clean install 时,会出现此问题:

错误

***************************
APPLICATION FAILED TO START
***************************

**Description**:

Field userService in com.example.accessingdatamysql.rest.MainController required a bean of type 'com.example.accessingdatamysql.service.UserService' that could not be found.

The injection point has the following annotations:
        - @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'com.example.accessingdatamysql.service.UserService' in your configuration.

问题是MainController中有“UserService”的导入:

package com.example.accessingdatamysql.rest;





import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.example.accessingdatamysql.model.dto.UserDto;
import com.example.accessingdatamysql.service.UserService;


@RestController
public class MainController {
  @Autowired 
         
private UserService userService;

  @Transactional
  @PostMapping(path="/demo/add")
  public @ResponseBody String addNewUser (@RequestParam String name
      , @RequestParam String email,@RequestParam String surname) 
  {
 

    UserDto n = new UserDto();
    n.setName(name);
    n.setSurname(surname);
    n.setEmail(email);
    userService.create(n);
    return "Saved";
  }



 


  @GetMapping("/demo/first")
  public UserDto one(@RequestParam String name) {
   System.out.print(name);
  return userService.findFirstByName(name); 
  }
}
  

这可能是一件微不足道的事情,但我无法绕过这个问题,下面我插入“UserService”和MainStart

UserService.java

package com.example.accessingdatamysql.service;

import com.example.accessingdatamysql.model.dto.UserDto;

public interface UserService {

    UserDto findFirstByName(String name);
    
    void create(UserDto user);
        
}

更新: 我插入了 UserServiceImpl 和新的 main 和 Mapper,但出现了新的错误。

UserServiceImpl.java

package com.example.accessingdatamysql.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.accessingdatamysql.model.dto.UserDto;
import com.example.accessingdatamysql.model.entity.UserEntity;
import com.example.accessingdatamysql.model.repo.UserRepository;
import com.example.accessingdatamysql.util.UserMapper;

@Service
public class UserServiceImpl implements UserService{
    
    @Autowired
      private UserRepository userRepository;
    
    @Autowired
    UserMapper mapper;

    @Override
    public UserDto findFirstByName(String name) {
           UserEntity entity = userRepository.findFirstByName(name);
           
        return mapper.toDtoMapper(entity);
    }

    @Override
    public void create(UserDto user) {
         UserEntity entity = mapper.toEntityMapper(user);
         
         userRepository.create(entity);
        
    }
 
}

AccessingDataMysqlApplication.java

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;


@SpringBootApplication(scanBasePackages = { "com.example.accessingdatamysql",
"com.example.accessingdatamysql.util"})
public class AccessingDataMysqlApplication {

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

}

UserMapper.java

package com.example.accessingdatamysql.util;

import org.mapstruct.Mapper;

import com.example.accessingdatamysql.model.dto.UserDto;
import com.example.accessingdatamysql.model.entity.UserEntity;


@Mapper (componentModel = "spring")
public interface UserMapper {

    UserEntity toEntityMapper (UserDto user);
    
    UserDto toDtoMapper (UserEntity userEntity);
}

新错误

***************************
APPLICATION FAILED TO START
***************************

Description:

Field mapper in com.example.accessingdatamysql.service.UserServiceImpl required a bean of type 'com.example.accessingdatamysql.util.UserMapper' that could not be found.

The injection point has the following annotations:
        - @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'com.example.accessingdatamysql.util.UserMapper' in your configuration.

POM

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>accessingdatamysql</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>project</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
            </properties>

    <dependencies>
            <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>1.3.1.Final</version>
        </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-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

【问题讨论】:

    标签: java spring spring-boot maven spring-mvc


    【解决方案1】:

    使用@Service@Component 注释您的UserService 类实现[如UserServiceImpl.java]。还要确保这个类位于一个子包中。

    这是你的主类包:com.example.accessingdatamysql 您的 UserService 类和所有其他类应保存在一个包中,例如:com.example.accessingdatamysql.xxxxxx。确保遵循此策略。

    另外删除主类上不必要的注释。 @SpringBootApplication 注释等效于使用以下 3 : :

    1. @配置,
    2. @EnableAutoConfiguration 和
    3. @ComponentScan 与属性。

    这就够了:

    @SpringBootApplication (scanBasePackages = "com.example.accessingdatamysql")
    

    并且在自动装配任何 bean 注入时不要留有间隙。这不会造成任何伤害。但是你的代码应该被正确地组织和缩进。

    下面也替换:

     @Autowired 
             
    private UserService userService;
    

    有了这个:

     @Autowired          
     private UserService userService;
    

    UPDATE-1

    在修复 Spring Boot 配置后执行 Maven 全新安装。

    mvn 全新安装

    UPDATE-2

    您的 Mapper bean 不完全符合 Spring bean 的条件。您需要使用以下插件编译您的项目(请参阅我使用的第二个插件)。

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>1.3.1.Final</version>
                        </path>
                    </annotationProcessorPaths>
                    <compilerArgs>
                        <compilerArg>
                            -Amapstruct.defaultComponentModel=spring
                        </compilerArg>
                    </compilerArgs>
                </configuration>
            </plugin>
        </plugins>
    </build>
    

    然后您需要修复您的 UserDto.java 如下(更改时间戳变量的类型,否则 Mapper 将失败):

    import java.sql.Timestamp;
    
    
    
    
    private Timestamp timestamp;
    
    public Timestamp getTimestamp() {
        return timestamp;
    }
    
    public void setTimestamp(Timestamp timestamp) {
        this.timestamp = timestamp;
    }
    

    你的主类应该只有这个:@SpringBootApplication (scanBasePackages = "com.example.accessingdatamysql") 而没有其他注释。

    然后保存您的项目。然后运行:mvn clean install -X

    让你的包结构像这样:

    你的课程安排如下:

    【讨论】:

    • 嗨,索姆!我加载了 UserServiceImpl 类、Mapper 和新的 Main,但现在我遇到了类似的映射器问题,即使在我看来 Autowireds 放置正确
    • 执行 maven 全新安装,这将解决您的问题。例如:mvn clean install
    • 您能否粘贴您为@Mapper 获得的确切错误
    • 我把错误放在了UPDATE中,如果你的意思是maven返回给我的,我插入它
    • 尝试将此构造函数保留在您的 Mapper 类中。 public UserMapper INSTANCE = Mappers.getMapper( UserMapper .class ); 我认为你的配置是正确的。 maven clean build 应该可以解决您的问题。还要检查您是否正在为您的 Mapper 使用任何实现,或者您只是使用默认配置。
    【解决方案2】:

    在这种情况下,您需要定义一个 bean 让 Spring 使用它们,例如 DI(Dependency Injection) @Autowired

    有多种方法可以定义 bean,但在您的情况下,在服务类上使用 @Service 注释,以便 Spring 可以在初始化期间找到它。

    而且您不需要声明 @ComponentScan 注释,@SpringbootApplication 将处理所有事情。

    正如@Som 所说,您需要实现您的Userservice 类,因为它是接口并且还没有实现的类。

    尝试去掉@ComponentScan注解,实现UserService接口如下

    @Service
    public class UserServiceImpl implements UserService{
        // the rest of the code
    }
    

    【讨论】:

    • 嗨!我加载了 UserServiceImpl 类、Mapper 和新的 Main,但现在我遇到了类似的映射器问题,即使在我看来 Autowireds 放置正确
    • 试过了,没什么变化
    • @Jacket 抱歉,我最后的评论是错误的。查看link
    猜你喜欢
    • 2019-12-05
    • 2022-06-17
    • 2021-03-18
    • 2021-11-25
    • 1970-01-01
    • 2018-08-03
    • 2017-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多