Java SpringBoot - BeanDefinitionOverrideException:无效的 bean 定义
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/53723303/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
SpringBoot - BeanDefinitionOverrideException: Invalid bean definition
提问by Vino
I am trying to setup DynamoDB locally with Spring Boot. Initially I got the setup working and was able to write/save to DynamoDB via a repository. From that point I added more classes to build my application. Now when I try to start my application, I get the following exception:
我正在尝试使用 Spring Boot 在本地设置 DynamoDB。最初,我使设置正常工作,并且能够通过存储库写入/保存到 DynamoDB。从那时起,我添加了更多类来构建我的应用程序。现在,当我尝试启动我的应用程序时,出现以下异常:
org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'agentRepository' defined in null: Cannot register bean definition [Root bean: class [org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBRepositoryFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] for bean 'agentRepository': There is already [Root bean: class [org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBRepositoryFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] bound.
org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'agentRepository' defined in null: Cannot register bean definition [Root bean: class [org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBRepositoryFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] for bean 'agentRepository': There is already [Root bean: class [org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBRepositoryFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] bound.
I have searched SO and internet extensively but there were no any useful solution to this. The error message is misleading as well.
我已经广泛搜索了 SO 和互联网,但没有任何有用的解决方案。错误消息也具有误导性。
My project is of the following hierarchy
我的项目具有以下层次结构
ai.test.as
- as
- agent
- business
- intent
- exception
- Agent.java
- AgentDTO.java
- AgentRespository.java
- AgentController.java
- AgentService.java
- AgentServiceImpl.java
- config
- DynamoDBConfig.java
DynamoDBConfig.java
DynamoDBConfig.java
package ai.test.as.config;
import ai.test.as.agent.AgentRepository;
import ai.test.as.agent.intent.template.TemplateRepository;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import org.socialsignin.spring.data.dynamodb.repository.config.EnableDynamoDBRepositories;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableDynamoDBRepositories(basePackageClasses = {AgentRepository.class})
public class DynamoDBConfig
{
@Value("${aws.dynamodb.endpoint}")
private String dynamoDBEndpoint;
@Value("${aws.auth.accesskey}")
private String awsAccessKey;
@Value("${aws.auth.secretkey}")
private String awsSecretKey;
@Bean
public AmazonDynamoDB amazonDynamoDB()
{
AmazonDynamoDB dynamoDB = new AmazonDynamoDBClient(getAwsCredentials());
dynamoDB.setEndpoint(dynamoDBEndpoint);
return dynamoDB;
}
@Bean
public AWSCredentials getAwsCredentials()
{
return new BasicAWSCredentials(awsAccessKey, awsSecretKey);
}
}
AgentRepository.java
AgentRepository.java
package ai.test.as.agent;
import ai.test.as.agent.Agent;
import org.socialsignin.spring.data.dynamodb.repository.EnableScan;
import org.springframework.data.repository.CrudRepository;
@EnableScan
public interface AgentRepository extends CrudRepository<Agent, String>
{
}
AgentController.java (Where AgentRepository is used)
AgentController.java(使用 AgentRepository 的地方)
@RestController
@RequestMapping(value = "/v1/agents")
public class AgentController
{
@Autowired
private AgentRepository agentRepository;
@RequestMapping(value = "/test", method = RequestMethod.POST)
public void test()
{
Agent agent = new Agent();
agent.setAgentNumber("123456");
agent.setId(1);
agentRepository.save(agent);
}
}
Spring suggests the following:
> The bean 'agentRepository', defined in null, could not be registered. A bean with that name has already been defined in null and overriding is disabled
.
春天提出以下建议:
> The bean 'agentRepository', defined in null, could not be registered. A bean with that name has already been defined in null and overriding is disabled
。
What does null
mean here? Is it because something wrong in my application config? Also how is it possible that it is already registered?
null
这里是什么意思?是因为我的应用程序配置有问题吗?还有它怎么可能已经注册了?
Please give me some pointers because I so confused about my next steps.
请给我一些指示,因为我对接下来的步骤感到很困惑。
采纳答案by Darren Forsythe
Bean overriding has to be enabled since Spring Boot 2.1,
自 Spring Boot 2.1 起必须启用 Bean 覆盖,
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.1-Release-Notes
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.1-Release-Notes
Bean Overriding
Bean overriding has been disabled by default to prevent a bean being accidentally overridden. If you are relying on overriding, you will need to set spring.main.allow-bean-definition-overriding to true.
Bean覆盖
默认情况下已禁用 Bean 覆盖,以防止 Bean 被意外覆盖。如果您依赖覆盖,则需要将 spring.main.allow-bean-definition-overriding 设置为 true。
Set
放
spring.main.allow-bean-definition-overriding=true
or yml,
或yml,
spring:
main:
allow-bean-definition-overriding: true
to enable overriding again.
再次启用覆盖。
Edit,
编辑,
Bean Overriding is based of the name of the bean not its type. e.g.
Bean Overriding 是基于 bean 的名称而不是它的类型。例如
@Bean
public ClassA class(){
return new ClassA();
}
@Bean
public ClassB class(){
return new ClassB();
}
Will cause this error in > 2.1, by default bean names are taken from the method name. Renaming the method or adding the name
attribute to the Bean
annotation will be a valid fix.
在> 2.1 中会导致此错误,默认情况下bean 名称取自方法名称。重命名方法或将name
属性添加到Bean
注释将是一个有效的修复。
回答by Shell Scott
Enable bean overriding with such approach for example
例如,使用这种方法启用 bean 覆盖
@SpringBootTest(properties = "spring.main.allow-bean-definition-overriding=true")
or
或者
@SpringBootApplication (properties = "spring.main.allow-bean-definition-overriding=true")
回答by Sascha Doerdelmann
I think I had the same problem with MongoDB. At least the error message looked exactly the same and I also had just one repository for the MongoDB, something like this:
我想我对 MongoDB 也有同样的问题。至少错误消息看起来完全一样,而且我也只有一个 MongoDB 存储库,如下所示:
public interface MyClassMongoRepository extends MongoRepository<MyClass, Long> {
}
The problem had been caused by class MyClass which had been used in another database before. Spring silently created some JpaRepository before creating the MongoRepository. Both repositories had the same name which caused the conflict.
该问题是由之前在另一个数据库中使用过的类 MyClass 引起的。Spring 在创建 MongoRepository 之前默默地创建了一些 JpaRepository。两个存储库的名称相同,这导致了冲突。
Solution was to make a copy of MyClass, move it into the package of the MongoRepository and remove any JPA-specific annotations.
解决方案是制作 MyClass 的副本,将其移动到 MongoRepository 的包中并删除任何特定于 JPA 的注释。