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