001package io.avaje.inject;
002
003import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
004import static java.lang.annotation.ElementType.METHOD;
005import static java.lang.annotation.ElementType.TYPE;
006import static java.lang.annotation.RetentionPolicy.CLASS;
007import static java.lang.annotation.RetentionPolicy.RUNTIME;
008
009import java.lang.annotation.Repeatable;
010import java.lang.annotation.Retention;
011import java.lang.annotation.Target;
012
013/**
014 * Expresses a requirement for a bean to be wired/registered into the {@link BeanScope}.
015 *
016 * <pre>{@code
017 *
018 *   @Factory
019 *   public class MyAutoConfiguration {
020 *
021 *     @Bean
022 *     @RequiresBean(OtherService.class)
023 *     public MyService myService() {
024 *         ...
025 *     }
026 *   }
027 *
028 * }</pre>
029 *
030 * <p>In the sample above the MyService bean will get wired only if a bean of type {@code
031 * OtherService} is already registered in the {@link BeanScope}.
032 */
033@Retention(CLASS)
034@Repeatable(RequiresBean.Container.class)
035@Target({TYPE, METHOD, ANNOTATION_TYPE})
036public @interface RequiresBean {
037
038  /**
039   * Expresses that beans of the given types should be available in the {@link BeanScope}.
040   *
041   * @return the class types of beans to check
042   */
043  Class<?>[] value() default {};
044
045  /**
046   * Expresses that beans of the given types should not be available in the {@link BeanScope}.
047   *
048   * @return the class types of beans to check
049   */
050  Class<?>[] missing() default {};
051
052  /**
053   * Expresses that a {@code @Named} or {@code @Qualifier} annotation marker of the given name should be
054   * available in the {@link BeanScope}.
055   *
056   * @return the names of beans to check
057   */
058  String[] qualifiers() default {};
059
060  @Retention(RUNTIME)
061  @Target({TYPE, METHOD, ANNOTATION_TYPE})
062  @interface Container {
063
064    /**
065     * The required dependencies.
066     */
067    RequiresBean[] value();
068  }
069}