001package io.avaje.inject;
002
003import java.lang.annotation.ElementType;
004import java.lang.annotation.Retention;
005import java.lang.annotation.RetentionPolicy;
006import java.lang.annotation.Target;
007
008import static java.lang.annotation.ElementType.MODULE;
009import static java.lang.annotation.ElementType.PACKAGE;
010import static java.lang.annotation.ElementType.TYPE;
011import static java.lang.annotation.RetentionPolicy.CLASS;
012
013/**
014 * Identify a bean as component with singleton scope that avaje-inject will use.
015 * <p>
016 * This is an alternative to using the standard <code>@Singleton</code> annotation.
017 * We generally use <code>@Component</code> when we:
018 * <ul>
019 *   <li>Want to use avaje-inject in a project that has some other library using <code>@Singleton</code></li>
020 *   <li>Want to support BOTH <code>javax.inject</code> and <code>jakarta.inject</code></li>
021 * </ul>
022 *
023 * <h3>Example</h3>
024 * <pre>{@code
025 *
026 * @Component
027 * class MyEmailSender implements EmailSender {
028 *
029 *   ...
030 * }
031 * }</pre>
032 *
033 * <h3>Ignoring <em>@Singleton</em></h3>
034 * <p>
035 * Set {@link InjectModule#ignoreSingleton()} <code>true</code> to get avaje-inject to ignore
036 * classes annotated with <code>@Singleton</code>. Typically, we want another DI library to use
037 * those classes and want avaje-inject to co-exist independently.
038 * <p>
039 *
040 * <pre>{@code
041 *
042 *   @InjectModule(name = "coffee", ignoreSingleton = true)
043 *   package coffee;
044 *
045 *   import io.avaje.inject.InjectModule;
046 *
047 * }</pre>
048 *
049 * @see InjectModule#ignoreSingleton()
050 */
051@Target(ElementType.TYPE)
052@Retention(RetentionPolicy.RUNTIME)
053public @interface Component {
054
055  /**
056   * Specify types to generate DI classes for. To avoid package splitting, the imported DI classes
057   *
058   * <p>These types are typically in an external project / dependency or otherwise types that we
059   * can't or don't want to explicitly annotate with {@code @Singleton}/{@code @Component}.
060   *
061   * <p>Typically, we put this annotation on a package/module-info.
062   *
063   * <pre>{@code
064   * Component.Import({CustomerService.class, ProductService.class, ...})
065   * package org.example.processor;
066   *
067   * }</pre>
068   */
069  @Retention(CLASS)
070  @Target({TYPE, PACKAGE, MODULE})
071  @interface Import {
072
073    /** Specify types to generate DI classes for. */
074    Class<?>[] value();
075  }
076}