Java 如何基于限定符注释以编程方式自动关联bean

Java 如何基于限定符注释以编程方式自动关联bean,java,spring-boot,spring-junit,junit5-extension-model,Java,Spring Boot,Spring Junit,Junit5 Extension Model,在Junit5中,当使用扩展时,我们可以运行BeforeAll和aftereall方法,我正在尝试使用注释来改变测试的行为。 然而,我也将这些注释用作@qualifier来初始化bean,并且希望能够使用测试中标识的注释初始化bean 我希望在运行时使用限定符注释以编程方式初始化Bean 我知道Junit5的SpringExtension可以 SpringExtension.getApplicationContext(context).getAutowireCapableBeanFactory(

在Junit5中,当使用扩展时,我们可以运行BeforeAll和aftereall方法,我正在尝试使用注释来改变测试的行为。 然而,我也将这些注释用作@qualifier来初始化bean,并且希望能够使用测试中标识的注释初始化bean

我希望在运行时使用限定符注释以编程方式初始化Bean 我知道Junit5的SpringExtension可以

SpringExtension.getApplicationContext(context).getAutowireCapableBeanFactory()
使用它,我可以调用bean初始化工厂,但我不知道如何使用作为限定符的注释初始化bean 我有多个相同类型的bean,由限定符标识

我遇到的问题是

目前,我正在使用AutoWired静态初始化用户凭据的类型,然后根据注释使用预先初始化的UserCredential using switch case

我们的想法是使用一个测试类
@ExtendsWith(ResetPortal.class)
,然后它指出可以使用哪种类型的用户来重置(测试前登录)。 我使用限定符注释来表示这一点,然后我可以从Junit5
beforeAll
方法的
ExtensionContext
中提取它

此外,我有一个
UserCredential
类,并为该类为每种类型的用户定义了多个@Bean

代码

Bean定义,使用自定义限定符注释User1Qualifier

@Bean
  @User1Qualifier
  public static UserCredentials clientBankLogin(
      @Value(LOGIN_USERNAME_1) String username,
      @Value(LOGIN_PASSWORD_1) String password) {
    return new UserCredentials(username, password);
  }
我的自定义限定符如下(有多个)

现在,在测试中,我尝试使用ResetPortal拾取的相同注释

@SpringBootTest
@ExtendWith({ResetPortal.class, SpringExtension.class})
final class LoginTest extends SpringTestBase {

      @Test
      @User1Qualifier
      void clientLogin() {}
}
由于Junit5初始化该类并调用其托管实例,ResetPortal类需要单独定义自动连接元素

@Service
public class ResetPortal implements BeforeEachCallback, AfterEachCallback {

     static UserCredentials user1;
     static UserCredentials user2;

     Autowired
     public void initializeLoginToPortal(@User1Qualifier UserCredentials u1, 
                                         @User2Qualifier UserCredentials u2) {
                 user1 = u1;
                 user2 = u2;
    }

    @Override
      public void beforeEach(ExtensionContext context) {

      // This is the custom Value annotation marked on each UserQualifier
      // This is using AnnotationUtils#findAnnotation(java.lang.Class<?>, java.lang.Class<A>)
      CustomValueAnnotation loginAs = getLoginAsAnnotation(context);

      switch (loginAs){
       case "User1" : loginWith(ResetPortal.user1); break;
       case "User2" : loginWith(ResetPortal.user2); break;
      }
    }
}
@服务
公共类ResetPortal在每次回调之前、之后实现{
静态用户凭证user1;
静态user2;
自动装配
public void initializeLoginToPortal(@User1Qualifier UserCredentials u1,
@用户2限定符用户凭据(u2){
user1=u1;
user2=u2;
}
@凌驾
每个之前的公共无效(ExtensionContext上下文){
//这是在每个UserQualifier上标记的自定义值注释
//这是使用AnnotationUtils#findAnnotation(java.lang.Class,java.lang.Class)
CustomValueAnnotation loginAs=getLoginAsAnnotation(上下文);
交换机(登录){
案例“User1”:loginWith(ResetPortal.User1);中断;
案例“User2”:loginWith(ResetPortal.User2);中断;
}
}
}
@Service
public class ResetPortal implements BeforeEachCallback, AfterEachCallback {

     static UserCredentials user1;
     static UserCredentials user2;

     Autowired
     public void initializeLoginToPortal(@User1Qualifier UserCredentials u1, 
                                         @User2Qualifier UserCredentials u2) {
                 user1 = u1;
                 user2 = u2;
    }

    @Override
      public void beforeEach(ExtensionContext context) {

      // This is the custom Value annotation marked on each UserQualifier
      // This is using AnnotationUtils#findAnnotation(java.lang.Class<?>, java.lang.Class<A>)
      CustomValueAnnotation loginAs = getLoginAsAnnotation(context);

      switch (loginAs){
       case "User1" : loginWith(ResetPortal.user1); break;
       case "User2" : loginWith(ResetPortal.user2); break;
      }
    }
}