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