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