首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >通过构造函数参数2表示的不满意的依赖关系

通过构造函数参数2表示的不满意的依赖关系
EN

Stack Overflow用户
提问于 2020-01-06 16:21:14
回答 2查看 1.1K关注 0票数 0

我将spring从2.1.1升级到2.2.0。从那时起,当我启动我的应用程序时,我会遇到以下错误: org.springframework.beans.factory.NoUniqueBeanDefinitionException:,没有ParentService类型的合格bean :预期的单个匹配bean,但是找到了2: MasterService,SlaveService。

ParentService是一个接口:

代码语言:javascript
运行
复制
public interface ParentService{
..
}

MasterService:

代码语言:javascript
运行
复制
@Service
@MasterProfile
public class MasterService implements ParentService{
.....
}

SlaveService:

代码语言:javascript
运行
复制
@Service
@SlaveProfile
public class SlaveService implements ParentService{
.....
}

MasterProfile注释:

代码语言:javascript
运行
复制
@Profile("MASTER")
public @interface MasterProfile {

}

奴隶简介:

代码语言:javascript
运行
复制
@Profile("SLAVE")
public @interface SlaveProfile{

}

我将带有以下标志的配置文件传递给我的应用程序:

代码语言:javascript
运行
复制
-Dspring.profiles.include=MASTER

根据 Spring2.2发行说明的说法,它们已经做了一些更改,并且在maven中默认启用了叉子。因此,传递params的唯一方法是使用参数-Dspring-boot.run.jvmArguments 。我使用了-Dspring-boot.run.jvmArguments=-Dspring.profiles.include=MASTER ,但是它还是失败了。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-06 16:50:12

将配置文件作为参数传递取决于您如何运行应用程序。请小心,您提到的文档是指maven spring-boot plugin

  • 使用maven插件:mvn spring-boot:run -Dspring-boot.run.jvmArguments=-Dspring.profiles.include=MASTER
  • 经典java应用程序:java -Dspring.profiles.include=MASTER -jar ./myapp.jar

在这两个cmd行中,如果用,分隔,则可以传递多个参数。请参阅文档:https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config-profile-specific-properties

升级之后,您现在必须定义自定义配置文件注释,如下所示:

代码语言:javascript
运行
复制
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME) // Only this one is really needed
@Profile("SLAVE")
public @interface SlaveProfile {
}

解释:

在java中,注释有一个RetentionPolicy,类似于一个作用域。(参见:https://docs.oracle.com/javase/7/docs/api/java/lang/annotation/RetentionPolicy.html)。

如果没有任何RetentionPolicy集,默认行为是JVM不可见的注释(即在运行时)。

当您想运行您的应用程序时,首先编译它,这意味着将您的.java文件转换为.class文件。您的类只是一堆字节代码,将人类可读的文件转换为计算机语言。

然后,当Spring加载ApplicationContext时,它在幕后所做的事情,以及其他许多事情,就是读取您的.class文件。在此过程中(请参阅类名:org.springframework.asm.ClassReader),Spring加载您声明的注释。在运行时,我已经说过,您最终得到了“两种”注释:

  • InvisibleAnnotation:@保留(RetentionPolicy.COMPILE)
  • VisibleAnnotation:@保留(RetentionPolicy.RUNTIME)

为了总结和理解为什么它以前是工作的:

  • Spring-boot 2.1.0使用spring-core-5.1.2,它在运行时解释可见的和不可见的注释,这解释了为什么@SlaveProfile@MasterProfile具有预期的行为。
  • Spring-boot 2.2.0使用spring-core-5.2.0,它只在运行时解释可见的注释,这解释了为什么@SlaveProfile@MasterProfile没有预期的行为。

假设Spring“静默地”修复了一个错误,在他们不应该阅读“无形注释”的时候,它却没有提到它。

希望能帮上忙!

票数 1
EN

Stack Overflow用户

发布于 2020-01-06 16:54:52

添加@Profile不会阻止bean被实例化。这导致了异常。将@Primary添加到应用程序不应该默认的任何bean中。

例如,将@Primary添加到MasterProfile bean中。

票数 -3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59615522

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档