英文:
Spring Boot @Mapper Bean creation issue : Application Failed to start. Error : Consider defining a bean of Type
问题
以下是翻译好的部分:
错误信息:
***************************
应用程序启动失败
***************************
**描述**:
com.example.accessingdatamysql.rest.MainController中的字段userService需要一个类型为'com.example.accessingdatamysql.service.UserService'的bean,但找不到该bean。
注入点具有以下注解:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
操作:
考虑在您的配置中定义一个类型为'com.example.accessingdatamysql.service.UserService'的bean。
问题出在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);
}
新错误:
***************************
应用程序启动失败
***************************
描述:
com.example.accessingdatamysql.service.UserServiceImpl中的字段mapper需要一个类型为'com.example.accessingdatamysql.util.UserMapper'的bean,但找不到该bean。
注入点具有以下注解:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
操作:
考虑在您的配置中定义一个类型为'com.example.accessingdatamysql.util.UserMapper'的bean。
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 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>
英文:
I am new to spring, when i try to do the mvn clean install
of my project this problem appears:
Error
***************************
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.
The problem is that in the MainController
there is the import of "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);
}
}
It is probably a trivial thing but I can not bypass the problem, below I insert "UserService" and the 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);
}
UPDATE :
I insert the UserServiceImpl and the new main and Mapper, with the new error.
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);
}
New Error:
***************************
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>
答案1
得分: 4
将您的UserService
类的实现(类似于UserServiceImpl.java
)使用@Service
或@Component
进行注解。同时确保该类位于一个子包中。
您的主类包是:com.example.accessingdatamysql
。您的UserService
类和所有其他类都应该放在一个包中,例如:com.example.accessingdatamysql.xxxxxx
。请确保遵循这个策略。
此外,移除主类上的不必要的注解。@SpringBootApplication
注解等效于以下三个注解的组合:
@Configuration
@EnableAutoConfiguration
- 带有属性的
@ComponentScan
以下内容足够了:
@SpringBootApplication(scanBasePackages = "com.example.accessingdatamysql")
在进行Bean注入时,不要在任何Bean注入之间留有空隙。这不会造成任何问题。但是您的代码应该被适当地组织和缩进。
还需要将以下内容替换为:
@Autowired
private UserService userService;
更新1
在修复Spring Boot配置后,执行mvn clean install
。
更新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
。
确保您的包结构如下所示:
(包结构的图片)
以及您的类按照以下方式排列:
(类在包中的图片)
英文:
Annotate your UserService class implementation [like UserServiceImpl.java
] with @Service
or @Component
. Also make sure this class is located in a sub-package.
This is your main class package : com.example.accessingdatamysql
Your UserService class and all other classes should be kept in a package like : com.example.accessingdatamysql.xxxxxx
. Ensure this strategy is followed.
Plus remove the unnecessary annotations on your main class. The @SpringBootApplication annotation is equivalent to using the below 3 :
:
- @Configuration,
- @EnableAutoConfiguration and
- @ComponentScan with attributes.
This will be enough :
@SpringBootApplication (scanBasePackages = "com.example.accessingdatamysql")
And do not keep a gap when you autowire any bean injection. This does not cause any harm. But your code should be properly organized and indentation done.
Also replace below :
@Autowired
private UserService userService;
With this :
@Autowired
private UserService userService;
UPDATE-1
Do a maven clean install after you fix your spring boot configurations.
mvn clean install
UPDATE-2
Your bean for Mapper does not fully qualify for a spring bean. You need to compile your project with the below plugin (see the 2nd plugin I have used).
<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>
Then you need to fix your UserDto.java as below (change the type of timestamp variable else Mapper will fail):
import java.sql.Timestamp;
private Timestamp timestamp;
public Timestamp getTimestamp() {
return timestamp;
}
public void setTimestamp(Timestamp timestamp) {
this.timestamp = timestamp;
}
Your main class should only have this : @SpringBootApplication (scanBasePackages = "com.example.accessingdatamysql")
and no other annotation.
Then save your project. And Then run : mvn clean install -X
Make your package structure like this :
And your classes arranged in the below way :
答案2
得分: 0
你需要定义一个Bean,让Spring可以使用它们,例如在这种情况下使用依赖注入(Dependency Injection)的@Autowired
。
有多种方法来定义这些Beans,但在你的情况下,可以在服务类上使用@Service
注解,这样Spring在初始化过程中就能找到它。
而且你不需要声明@ComponentScan
注解,@SpringbootApplication
会处理所有事情。
正如@Som所说,你需要实现你的UserService
类,因为它是一个接口,目前还没有实现的类。
尝试移除@ComponentScan
注解,并按照以下方式实现UserService
接口:
@Service
public class UserServiceImpl implements UserService{
// 其余的代码
}
英文:
You need to define a bean to let the Spring use them such as DI(Dependency Injection) @Autowired
in this case.
There are various ways to define the beans but in your case using @Service
annotation on the service class so that Spring can find it during the initialization.
And you don't need to declare @ComponentScan
annotation the @SpringbootApplication
will handle everything.
As @Som said, you need to implement your Userservice
class since it is interface and there is no implemented class yet.
Try to remove @ComponentScan
annotation and implement UserService
interface as follow
@Service
public class UserServiceImpl implements UserService{
// the rest of the code
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论