001package sting; 002 003import java.lang.annotation.Documented; 004import java.lang.annotation.ElementType; 005import java.lang.annotation.Retention; 006import java.lang.annotation.RetentionPolicy; 007import java.lang.annotation.Target; 008 009/** 010 * Annotates an interface for which a dependency-injected factory implementation is to be generated. 011 * This annotation is a top-level Sting processor entrypoint. The generated implementation is itself a 012 * Sting-managed component and publishes the factory interface via the {@link Typed} annotation. 013 * 014 * <h2>Generated Classname</h2> 015 * 016 * <p>The generated factory implementation uses the standard Sting naming convention and has the name of the 017 * annotated type prepended with {@code Sting_}. For example, the top-level type 018 * {@code mybiz.MyWidgetFactory} will produce the implementation {@code mybiz.Sting_MyWidgetFactory}. 019 * Nested types are also supported but their names have the {@code $} sign replaced with a {@code _}. 020 * i.e. The nested class named {@code mybiz.MyOuterClass.MyWidgetFactory} will generate an implementation 021 * named {@code mybiz.MyOuterClass_Sting_MyWidgetFactory}</p> 022 * 023 * <h2>Factory Methods</h2> 024 * 025 * <p>Abstract instance methods defined on the factory interface are treated as candidate factory methods. 026 * Each candidate method identifies a component type to create and the subset of constructor arguments that 027 * are supplied by the caller at runtime. The factory interface may also declare default methods and these are 028 * inherited by the generated implementation.</p> 029 * 030 * <p>Candidate factory methods must:</p> 031 * 032 * <ul> 033 * <li>return a concrete class type,</li> 034 * <li>not declare type parameters,</li> 035 * <li>not declare thrown exceptions, and</li> 036 * <li>have parameters whose names and types exactly match constructor parameters on the created type.</li> 037 * </ul> 038 * 039 * <p>The created type must have exactly one constructor accessible from the package containing the factory 040 * interface. Constructor parameters omitted from the factory method are treated as Sting-managed dependencies 041 * and are injected into the generated factory implementation. This makes it possible to combine services managed 042 * by Sting with runtime values supplied by application code.</p> 043 * 044 * <h2>Injector Integration</h2> 045 * 046 * <p>The {@link Factory} annotation is itself annotated with {@link StingProvider}, allowing the factory 047 * interface to be included in an {@link Injector#includes()} or {@link Fragment#includes()} list as a 048 * provider-backed type. 049 * The generated factory implementation is annotated as an {@link Injectable} and {@link Typed} component 050 * so other Sting-managed components can depend upon the factory interface.</p> 051 * 052 * <p>A single factory interface may define multiple factory methods that create different component types.</p> 053 * 054 * <p>Example:</p> 055 * 056 * <pre><code> 057 * class MyWidget { 058 * MyWidget( {@literal @}Nonnull BackendService backendService, int size ) { 059 * } 060 * } 061 * 062 * {@literal @}Factory 063 * interface MyWidgetFactory { 064 * {@literal @}Nonnull 065 * MyWidget create( int size ); 066 * } 067 * 068 * {@literal @}Injector( includes = MyWidgetFactory.class ) 069 * interface MyInjector { 070 * MyWidgetFactory widgetFactory(); 071 * } 072 * </code></pre> 073 * 074 * <p>In the example above, Sting generates a factory implementation that injects the {@code BackendService} 075 * dependency and accepts the {@code size} parameter from the caller when {@code create(int)} is invoked.</p> 076 */ 077@Documented 078@Retention( RetentionPolicy.RUNTIME ) 079@Target( ElementType.TYPE ) 080@StingProvider( "[FlatEnclosingName]Sting_[SimpleName]" ) 081public @interface Factory 082{ 083}