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
008/**
009 * Annotate a bean for which we want avaje-inject to generate a factory.
010 *
011 * <p>The bean will have some properties of normal dependency injection components and others that
012 * will be parameters to the method on the factory - these parameters are annotated with
013 * {@code @Assisted}.
014 *
015 * <h3>Example</h3>
016 *
017 * <p>Create an interface which we want avaje-inject to generate an implementation. We desire this
018 * because the factory has some managed dependencies that should be injected for us and some
019 * dependencies that are provided by the application (and annotated with {@code Assisted}).
020 *
021 * <p>The factory supertype must be a functional interface, or an abstract class with only one
022 * abstract method defined.
023 *
024 * <pre>{@code
025 * public interface CssFactory {
026 *
027 *   Scanner scanner(Path myPath);
028 * }
029 *
030 * }</pre>
031 *
032 * <p>Create a bean annotated with {@code @AssistFactory} that specifies the factory. Any
033 * dependencies that are annotated with {@code Assisted} will be parameters of the factory method,
034 * the other dependencies will be managed and injected by avaje-inject.
035 *
036 * <p>The {@code Assisted} parameters must match the factory method parameters by name and type. In
037 * this example, {@code Path myPath} match in both CssScanner and in CssFactory.
038 *
039 * <pre>{@code
040 * @AssistFactory(CssFactory.class)
041 * class CssScanner implements Scanner {
042 *
043 *   private final Path myPath;
044 *   private final SomeComponent someComponent;
045 *
046 *   CssScanner(@Assisted Path path, SomeComponent someComponent) {
047 *     this.path = path;
048 *     this.someComponent = someComponent;
049 *   }
050 *
051 *   ...
052 * }
053 *
054 * }</pre>
055 */
056@Target(ElementType.TYPE)
057@Retention(RetentionPolicy.RUNTIME)
058public @interface AssistFactory {
059
060  /** Specify the factory interface for which the implementation will be generated. */
061  Class<?> value();
062}