gpt4 book ai didi

java - 使用@Qualifier注释抛出 "NoUniqueBeanDefinitionException"(发现多个相同类型的bean)

转载 作者:行者123 更新时间:2023-12-02 09:32:31 24 4
gpt4 key购买 nike

问题

我收到错误

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'hello.storage.StorageService' available: expected single matching bean but found 2: service2,service1

当尝试启动我的 Spring 应用程序时。

这是由两个@Service引起的我创建的每个实现和接口(interface)的类,StorageService。我将这两个都命名为 @Service类(class)本身的类(class),@Service("service1")@Service("service2") ,我正在尝试 @Autowire @Controller中的每个类(class)构造函数并指定 @Service我想通过使用 @Qualifier直接在构造函数中的每个参数上进行注释,但我仍然收到 NoUniqueBeanDefinitionException错误。

我的期望

我只是希望 Spring 能够通过使用 @Qualifier 来区分这两个 Bean。注释。

代码

存储服务

package hello.storage;

import org.springframework.core.io.Resource;
import org.springframework.web.multipart.MultipartFile;

import java.nio.file.Path;
import java.util.stream.Stream;

public interface StorageService {

void init();

void store(MultipartFile file);

Stream<Path> loadAll();

Path load(String filename);

Resource loadAsResource(String filename);

void deleteAll();

}

文件系统存储服务

package hello.storage;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.util.FileSystemUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;

@Service("service1")
public class FileSystemStorageService implements StorageService {

private final Path rootLocation;

@Autowired
public FileSystemStorageService(StorageProperties properties) {
this.rootLocation = Paths.get(properties.getLocation());
}

@Override
public void store(MultipartFile file) {
try {
if (file.isEmpty()) {
throw new StorageException("Failed to store empty file " + file.getOriginalFilename());
}
Files.copy(file.getInputStream(), this.rootLocation.resolve(file.getOriginalFilename()));
} catch (IOException e) {
throw new StorageException("Failed to store file " + file.getOriginalFilename(), e);
}
}

@Override
public Stream<Path> loadAll() {
try {
return Files.walk(this.rootLocation, 1)
.filter(path -> !path.equals(this.rootLocation))
.map(path -> this.rootLocation.relativize(path));
} catch (IOException e) {
throw new StorageException("Failed to read stored files", e);
}

}

@Override
public Path load(String filename) {
return rootLocation.resolve(filename);
}

@Override
public Resource loadAsResource(String filename) {
try {
Path file = load(filename);
Resource resource = new UrlResource(file.toUri());
if(resource.exists() || resource.isReadable()) {
return resource;
}
else {
throw new StorageFileNotFoundException("Could not read file: " + filename);

}
} catch (MalformedURLException e) {
throw new StorageFileNotFoundException("Could not read file: " + filename, e);
}
}

@Override
public void deleteAll() {
FileSystemUtils.deleteRecursively(rootLocation.toFile());
}

@Override
public void init() {
try {
Files.createDirectory(rootLocation);
} catch (IOException e) {
throw new StorageException("Could not initialize storage", e);
}
}
}

AltFileSystemStorageService

package hello.storage;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.util.FileSystemUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;

@Service("service2")
public class AltFileSystemStorageService implements StorageService {

// Exactly the same as "FileSystemStorageService" this is just for testing/learning
}

FileUploadController

package hello;

import java.io.IOException;
import java.util.stream.Collectors;

import hello.storage.AltFileSystemStorageService;
import hello.storage.FileSystemStorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
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.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import hello.storage.StorageFileNotFoundException;
import hello.storage.StorageService;

@Controller
public class FileUploadController {

private final StorageService storageService;
private final StorageService altStorageService;

@Autowired
public FileUploadController(@Qualifier("service1") FileSystemStorageService storageService,
@Qualifier("service2") AltFileSystemStorageService altStorageService)
{
this.storageService = storageService;
this.altStorageService = altStorageService;
}

// Controller specific methods

}

申请

package hello;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

import hello.storage.StorageProperties;
import hello.storage.StorageService;

@SpringBootApplication
@EnableConfigurationProperties(StorageProperties.class)
public class Application {

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

@Bean
CommandLineRunner init(StorageService storageService) {
return (args) -> {
storageService.deleteAll();
storageService.init();
};
}
}

我相信抛出异常是因为 FileUploadController但我也认为我正在使用 @Qualifier注释正确。

我检查过的内容

我已经查看了 SO 的多个示例,但似乎没有任何效果。

完整的异常堆栈

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

Description:

Parameter 0 of method init in hello.Application required a single bean, but 2 were found:
- service2: defined in file [/UploadFiles/initial/target/classes/hello/storage/AltFileSystemStorageService.class]
- service1: defined in file [/UploadFiles/initial/target/classes/hello/storage/FileSystemStorageService.class]


Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

[WARNING]
java.lang.reflect.InvocationTargetException
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.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:542)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'init' defined in hello.Application: Unsatisfied dependency expressed through method 'init' parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'hello.storage.StorageService' available: expected single matching bean but found 2: service2,service1
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:769)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:509)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1321)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1160)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
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:845)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:742)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:389)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1213)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1202)
at hello.Application.main(Application.java:17)
... 6 more
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'hello.storage.StorageService' available: expected single matching bean but found 2: service2,service1
at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:221)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1229)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1171)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:857)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:760)
... 25 more
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.838 s
[INFO] Finished at: 2019-09-07T13:21:10-04:00
[INFO] Final Memory: 34M/120M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.1.6.RELEASE:run (default-cli) on project gs-uploading-files: An exception occurred while running. null: InvocationTargetException: Error creating bean with name 'init' defined in hello.Application: Unsatisfied dependency expressed through method 'init' parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'hello.storage.StorageService' available: expected single matching bean but found 2: service2,service1 -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

最佳答案

我认为您应该将@Qualifier添加到CommandLineRunner:

@Bean
CommandLineRunner init(@Qualifier("service1") StorageService storageService)

关于java - 使用@Qualifier注释抛出 "NoUniqueBeanDefinitionException"(发现多个相同类型的bean),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57836029/

24 4 0
文章推荐: java - 包含特定元素的列表
文章推荐: java - 如何从保存 List<> 对象的文件中反序列化?
文章推荐: java - 为什么模拟对象没有得到方法调用?
文章推荐: java - Selenium Select 不适用于