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 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 for which to generate an implementation.
018 *
019 * <p>The factory interface must either be a functional interface, or an abstract class with only one
020 * abstract method defined.
021 *
022 * <pre>{@code
023 * public interface CssFactory {
024 *
025 *   Scanner scanner(Path myPath);
026 * }
027 *
028 * }</pre>
029 *
030 * <p>Create a bean annotated with {@code @AssistFactory} that specifies the same factory interface. Any
031 * dependencies annotated with {@code Assisted} must be parameters of the factory method,
032 * the other dependencies will be managed and injected.
033 *
034 * <p>The {@code Assisted} parameters must match the factory method parameters by name and type. In
035 * this example, {@code Path myPath} match in both CssScanner and in CssFactory.
036 *
037 * <pre>{@code
038 * @AssistFactory(CssFactory.class)
039 * class CssScanner implements Scanner {
040 *
041 *   private final Path myPath;
042 *   private final SomeComponent someComponent;
043 *
044 *   CssScanner(@Assisted Path path, SomeComponent someComponent) {
045 *     this.path = path;
046 *     this.someComponent = someComponent;
047 *   }
048 *
049 *   ...
050 * }
051 *
052 * }</pre>
053 */
054@Target(ElementType.TYPE)
055@Retention(RetentionPolicy.SOURCE)
056public @interface AssistFactory {
057
058  /** Specify the factory interface for which the implementation will be generated. */
059  Class<?> value();
060}