Поиск прототипа bean по пользовательскому атрибуту аннотации - PullRequest
0 голосов
/ 14 июня 2019

У меня есть пользовательская аннотация квалификатора

@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface MyQualifier {
    MyQualiferEnum value();
}

И некоторые бины

@Component
@Scope("prototype")
@MyQualifier(MyQualifierEnum.BLACK)
public class BlackBean {

@Component
@Scope("prototype")
@MyQualifier(MyQualifierEnum.WHITE)
public class WhiteBean {

Я пытаюсь @Lookup, но это зависит от имени или класса бина, и я не могу передать аннотацию иэто приписывает метод поиска

Тогда я пытаюсь

context.getgetBeansWithAnnotation(MyQualifier.class)

, но это приводит ко всем экземплярам бина @MyQualifier, что хуже для меня.

Я не могу представить @MyQualifierBlack, @MyQualiferWhite и т. Д. - отдельные аннотации, мне точно нужно перечисление, поэтому как я могу внедрить эти bean-объекты-прототипы, зависит от значения MyQualifierEnum, например MyQualifierEnum.BLACK, во время выполнения без ненужной инициализации других аннотированных bean-компонентов @MyQualifier?

1 Ответ

0 голосов
/ 17 июня 2019

В следующей настройке используются только JSR-330 аннотации. Я еще не тестировал его на весну, но он работает, например, с помощью hk2 в качестве реализации:

@MyQualifier(MyQualifierEnum.BLACK)
// Framework-specific annotations, e.g. @Component/@Service and @Scope
public class BlackService implements QualifiableService { }

@MyQualifier(MyQualifierEnum.WHITE)
// Framework-specific annotations, e.g. @Component/@Service and @Scope
public class WhiteService implements QualifiableService { }

@Qualifier
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface MyQualifier {

    public static enum MyQualifierEnum {
        WHITE, BLACK;
    }

    MyQualifier.MyQualifierEnum value();
}

// Framework-specific annotations
public interface QualifiableService { }

// Framework-specific annotations, e.g. @Component/@Service and @Scope
public class TestComponent {

    @MyQualifier(MyQualifierEnum.BLACK)
    @Inject
    private QualifiableService black;

    @MyQualifier(MyQualifierEnum.WHITE)
    @Inject
    private QualifiableService white;

    @MyQualifier(MyQualifierEnum.WHITE)
    @Inject
    private Provider<QualifiableService> whiteProvider;

    @MyQualifier(MyQualifierEnum.BLACK)
    @Inject
    private Provider<QualifiableService> blackProvider;

    void test() {
        final QualifiableService white = whiteProvider.get();
        final QualifiableService black = blackProvider.get();
    }
}

Убедитесь, что вы зарегистрировали обе реализации (например, сканирование пакетов в вашем случае) и вставили правильную через спецификатор. Реализация аннотаций равна должна быть достаточной для обеспечения правильного внедрения компонента.

В случае, если вы используете более узкую область (например, область действия прототипа), использование (квалифицированного) Provider кажется самым простым решением. В качестве альтернативы вы можете попробовать ввести прокси (например, используя механизм прокси springs).

...