1.概述
当我们有多个相同类型的实现时,命名Spring bean会很有帮助。这是因为,如果我们的bean没有唯一的名称,Spring会注入一个bean。
通过控制bean的命名,我们可以告诉Spring我们要将哪个bean注入目标对象。
在本文中,我们将讨论Spring bean的命名策略,并探讨如何为单一类型的bean提供多个名称。
2.默认Bean命名策略
Spring提供了多个用于创建bean的注解。我们可以在不同级别使用这些注解。例如,我们可以在bean类上放置一些注解,而在创建bean的方法上放置其他注解。
首先,让我们看看Spring的默认命名策略。当我们只指定没有任何值的注释时,Spring如何命名我们的bean?
2.1 类级注解
让我们从类级别使用的注释的默认命名策略开始。为了命名bean, Spring使用类名并将第一个字母转换为小写。
让我们看一个例子:
@Service
public class LoggingService {
}
在这里,Spring为类LoggingService
创建了一个bean,并使用名称“ loggingService
”注册了它。
相同的默认命名策略适用于用于创建Spring bean的所有类级别的注释,例如@Component
, @Service
@Controller
。
2.2 方法级注解
Spring提供了@Bean
和@Qualifier
类的注解,可用于创建bean的方法。
让我们看一个示例,以了解@Bean
注解的默认命名策略:
@Configuration
public class AuditConfiguration {
@Bean
public AuditService audit() {
return new AuditService();
}
}
在此配置类中,Spring在名称“ audit
” AuditService
的bean,因为当我们在方法上@Bean
**批注时,Spring会将方法名称用作bean名称**。
我们还可以@Qualifier
批注,下面将提供一个示例。
3. Bean的自定义命名
当我们需要在相同的Spring上下文中创建多个相同类型的bean时,可以为这些bean提供自定义名称,并使用这些名称引用它们。
因此,让我们看看如何为Spring bean赋予自定义名称:
@Component("myBean")
public class MyCustomComponent {
}
这次,Spring将创建名称为“ myBean
”的MyCustomComponent
当我们为bean明确命名时,Spring将使用该名称,然后可以使用该名称来引用或访问bean。
类似于@Component(“myBean”)
,我们可以使用其他注释来指定名称,例如@Service(“myService”)
, @Controller(“myController”)
和@Bean(“myCustomBean”)
,然后Spring将注册具有给定名称的那个bean。
4.用@Bean
和@Qualifier
4.1 @Bean
与价值
正如我们前面所看到的, @Bean
注解是在方法级别应用的,默认情况下,Spring使用方法名称作为Bean名称。
可以覆盖默认的Bean名称-我们可以使用@Bean
批注指定值:
@Configuration
public class MyConfiguration {
@Bean("beanComponent")
public MyCustomComponent myComponent() {
return new MyCustomComponent();
}
}
在这种情况下,当我们要获取类型为MyCustomComponent
的bean时,可以使用名称“ beanComponent
”来引用该bean。
Spring @Bean
批注通常在配置类方法中声明。它可以通过直接调用它们@Bean
4.2 @Qualifier
有价值
我们还可以使用@Qualifier
批注来命名bean。
首先,让我们创建一个接口Animal
,该接口将由多个类实现:
public interface Animal {
String name();
}
现在,让我们定义一个实现类Cat
并向其添加@Qualifier
批注,其值为“ cat
”:
@Component
@Qualifier("cat")
public class Cat implements Animal {
@Override
public String name() {
return "Cat";
}
}
Animal
的另一种实现, @Qualifier
和值“ dog
”对其进行注释:
@Component
@Qualifier("dog")
public class Dog implements Animal {
@Override
public String name() {
return "Dog";
}
}
现在,让我们编写一个PetShow
类,在其中可以注入Animal
的两个不同实例:
@Service
public class PetShow {
private final Animal dog;
private final Animal cat;
public PetShow (@Qualifier("dog")Animal dog, @Qualifier("cat")Animal cat) {
this.dog = dog;
this.cat = cat;
}
public Animal getDog() {
return dog;
}
public Animal getCat() {
return cat;
}
}
Pet
Show,
类中,我们通过@Qualifier
Animal
类型的两种实现,并在每个批注的value属性中使用了合格的bean名称。每当我们使用此限定名时,Spring都会将具有该限定名的bean注入目标Bean中。
5.验证Bean名称
到目前为止,我们已经看到了不同的示例来演示如何给Spring bean命名。现在的问题是,我们如何验证或测试这一点?
让我们看一下验证该行为的单元测试:
@ExtendWith(SpringExtension.class)
public class SpringBeanNamingUnitTest {
private AnnotationConfigApplicationContext context;
@BeforeEach
void setUp() {
context = new AnnotationConfigApplicationContext();
context.scan("com.baeldung.springbean.naming");
context.refresh();
}
@Test
void givenMultipleImplementationsOfAnimal_whenFieldIsInjectedWithQualifiedName_thenTheSpecificBeanShouldGetInjected() {
PetShow petShow = (PetShow) context.getBean("petShow");
assertThat(petShow.getCat().getClass()).isEqualTo(Cat.class);
assertThat(petShow.getDog().getClass()).isEqualTo(Dog.class);
}
在此JUnit测试中,我们将setUp
AnnotationConfigApplicationContext
,该方法用于获取Bean。
然后,我们只需使用标准断言来验证Spring bean的类。
六,结论
在这篇快速文章中,我们研究了默认和自定义的Spring bean命名策略。
我们还了解了自定义Spring bean命名在需要管理多个相同类型bean的用例中如何有用。
0 评论