java理解概要文件中的主要注释
我试图从这个video中理解@Primary在@Profile中的行为
使用profile进行依赖注入。
文件应用程序中的活动配置文件。属性为english
,运行它会产生错误
expected single matching bean but found 2: helloWorldServiceEnglish,helloWorldServiceSpanish
在helloConfig中添加@Primary注释。java解决了这个错误:
@Bean
@Profile("english")
@Primary
public HelloWorldService helloWorldServiceEnglish(HelloWorldFactory factory) {
return factory.createHelloWorldService("en");
}
当我使用Profile自动连接时,只有一个名为english
的配置文件,那么为什么它要搜索其他没有@Profile注释的bean呢?添加@Primary如何改变这种行为
Spring是否首先在内部按类型扫描Autowire,并完全忽略@Profile,因为它会抛出错误expected single matching bean but found 2
你好。java
package com.spring.config;
import com.spring.services.HelloWorldFactory;
import com.spring.services.HelloWorldService;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
@Configuration
public class HelloConfig {
@Bean
public HelloWorldFactory helloWorldFactory() {
return new HelloWorldFactory();
}
@Bean
@Profile("english")
@Primary
public HelloWorldService helloWorldServiceEnglish(HelloWorldFactory factory) {
return factory.createHelloWorldService("en");
}
@Bean
@Qualifier("spanish")
public HelloWorldService helloWorldServiceSpanish(HelloWorldFactory factory) {
return factory.createHelloWorldService("es");
}
@Bean
@Profile("french")
public HelloWorldService helloWorldServiceFrench(HelloWorldFactory factory) {
return factory.createHelloWorldService("fr");
}
@Bean
@Profile("german")
public HelloWorldService helloWorldServiceGerman(HelloWorldFactory factory) {
return factory.createHelloWorldService("de");
}
@Bean
@Profile("polish")
public HelloWorldService helloWorldServicePolish(HelloWorldFactory factory) {
return factory.createHelloWorldService("pl");
}
@Bean
@Profile("russian")
public HelloWorldService helloWorldServiceRussian(HelloWorldFactory factory) {
return factory.createHelloWorldService("ru");
}
}
依赖注入应用程序。java
package com.spring.componentScan;
import com.spring.controllers.GreetingController;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan("com.spring")
public class DependencyInjectionApplication {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(DependencyInjectionApplication.class, args);
GreetingController controller = (GreetingController) ctx.getBean("greetingController");
controller.sayHello();
}
}
欢迎控制器。java
package com.spring.controllers;
import com.spring.services.HelloWorldService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
@Controller
public class GreetingController {
private HelloWorldService helloWorldService;
private HelloWorldService helloWorldServiceSpanish;
@Autowired
public void setHelloWorldService(HelloWorldService helloWorldService) {
this.helloWorldService = helloWorldService;
}
@Autowired
@Qualifier("spanish")
public void setHelloWorldServiceFrench(HelloWorldService helloWorldServiceSpanish) {
this.helloWorldServiceSpanish = helloWorldServiceSpanish;
}
public String sayHello() {
String greeting = helloWorldService.getGreeting();
System.out.println(helloWorldServiceSpanish.getGreeting());
System.out.println(greeting);
return greeting;
}
}
应用程序。属性 春天个人资料。主动=英语
# 1 楼答案
好的,你的例子没有更新最新的代码。但我假设您想要创建同一bean类型的多个实例,并将它们用于不同的语言。这很容易实现,你不需要
@Profile
和@Primary
来实现您需要的只是为bean实例分配限定符(或者使用spring默认分配的限定符)。以及这个限定符的注入bean
控制器:
更新
当有多个注入候选时,如果希望将一个bean实例作为优先级选项,通常会将bean标记为
@Primary
Official doc with good example@Profile
只是缩小了bean搜索的范围,但如果在同一个概要文件中有多个相同类型的bean,仍然需要进行解救(如果按类型自动连接,则按限定符自动连接仍然可以正常工作)开发人员通常这样做是为了避免最初的
NoUniqueBeanDefinitionException
# 2 楼答案
如果你考虑这个源代码
这里没有
@Profile
注释,这就是为什么Spring创建了多个相同类型的bean,如果您希望它们被不同地识别,请尝试通过@Bean(name="polish")
(或者Spring通过查看@Bean
方法名来指定它们),然后使用@Qualifier("polish")
自动连线