001package io.avaje.inject.spi; 002 003import java.lang.reflect.Type; 004import java.util.List; 005import java.util.Map; 006import java.util.Optional; 007import java.util.Set; 008import java.util.function.Consumer; 009import java.util.function.Function; 010 011import io.avaje.inject.BeanScope; 012import jakarta.inject.Provider; 013 014/** 015 * Mutable builder object used when building a bean scope. 016 */ 017public interface Builder { 018 019 /** 020 * Create the root level Builder. 021 * 022 * @param profiles Explicit profiles used 023 * @param suppliedBeans The list of beans (typically test doubles) supplied when building the context. 024 * @param enrichBeans The list of classes we want to have with mockito spy enhancement 025 * @param parent The parent BeanScope 026 * @param parentOverride When false do not add beans that already exist on the parent 027 */ 028 @SuppressWarnings("rawtypes") 029 static Builder newBuilder(Set<String> profiles, ConfigPropertyPlugin plugin, List<SuppliedBean> suppliedBeans, List<EnrichBean> enrichBeans, BeanScope parent, boolean parentOverride) { 030 if (suppliedBeans.isEmpty() && enrichBeans.isEmpty()) { 031 // simple case, no mocks or spies 032 return new DBuilder(profiles, plugin, parent, parentOverride); 033 } 034 return new DBuilderExtn(profiles, plugin, parent, parentOverride, suppliedBeans, enrichBeans); 035 } 036 037 /** 038 * Return true if the bean should be created and registered with the context. 039 * <p> 040 * Returning false means there has been a supplied bean already registered and 041 * that we should skip the creation and registration for this bean. 042 * 043 * @param name The qualifier name 044 * @param types The types that the bean implements and provides 045 */ 046 boolean isBeanAbsent(String name, Type... types); 047 048 /** 049 * Return true if the bean should be created and registered with the context. 050 * <p> 051 * Returning false means there has been a supplied bean already registered and 052 * that we should skip the creation and registration for this bean. 053 * 054 * @param types The types that the bean implements and provides 055 */ 056 default boolean isBeanAbsent(Type... types) { 057 return isBeanAbsent(null, types); 058 } 059 060 /** 061 * Register the next bean as having Primary priority. 062 * Highest priority, wired over any other matching beans. 063 */ 064 Builder asPrimary(); 065 066 /** 067 * Register the next bean as having Secondary priority. 068 * Lowest priority, wired when no other matching beans are available. 069 */ 070 Builder asSecondary(); 071 072 /** 073 * Register the next bean as having the given priority. Wired only if no other higher priority 074 * matching beans are available. 075 */ 076 Builder asPriority(int priority); 077 078 /** 079 * Register the next bean as having Prototype scope. 080 */ 081 Builder asPrototype(); 082 083 /** 084 * Register the provider into the context. 085 */ 086 <T> void registerProvider(Provider<T> provider); 087 088 /** 089 * Register the lazy provider into the context. 090 */ 091 default <T> void registerLazy(Provider<T> provider, Function<Provider<T>, T> proxyClassConstructor) { 092 register(proxyClassConstructor.apply(new OnceProvider<>(provider))); 093 } 094 095 /** 096 * Register the bean instance into the context. 097 * 098 * @param bean The bean instance that has been created. 099 */ 100 <T> T register(T bean); 101 102 /** 103 * Register the externally provided bean. 104 * 105 * @param type The type of the provided bean. 106 * @param bean The bean instance 107 */ 108 <T> void withBean(Class<T> type, T bean); 109 110 /** 111 * Add lifecycle PostConstruct method. 112 */ 113 void addPostConstruct(Runnable runnable); 114 115 /** 116 * Add lifecycle PostConstruct method. 117 */ 118 void addPostConstruct(Consumer<BeanScope> consumer); 119 120 /** 121 * Add lifecycle PreDestroy method. 122 */ 123 void addPreDestroy(AutoCloseable closeable); 124 125 /** 126 * Add lifecycle PreDestroy method with a given priority. 127 */ 128 void addPreDestroy(AutoCloseable closeable, int priority); 129 130 /** 131 * Check if the instance is AutoCloseable and if so register it with PreDestroy. 132 * 133 * @param maybeAutoCloseable An instance that might be AutoCloseable 134 */ 135 void addAutoClosable(Object maybeAutoCloseable); 136 137 /** 138 * Add field and method injection. 139 */ 140 void addInjector(Consumer<Builder> injector); 141 142 /** 143 * Get a dependency. 144 */ 145 <T> T get(Class<T> cls); 146 147 /** 148 * Get a named dependency. 149 */ 150 <T> T get(Class<T> cls, String name); 151 152 /** 153 * Get a dependency for the generic type. 154 */ 155 <T> T get(Type cls); 156 157 /** 158 * Get a named dependency for the generic type. 159 */ 160 <T> T get(Type cls, String name); 161 162 /** 163 * Get an optional dependency. 164 */ 165 <T> Optional<T> getOptional(Class<T> cls); 166 167 /** 168 * Get an optional named dependency. 169 */ 170 <T> Optional<T> getOptional(Class<T> cls, String name); 171 172 /** 173 * Get an optional dependency for the generic type. 174 */ 175 <T> Optional<T> getOptional(Type cls); 176 177 /** 178 * Get an optional named dependency for the generic type. 179 */ 180 <T> Optional<T> getOptional(Type cls, String name); 181 182 /** 183 * Get an optional dependency potentially returning null. 184 */ 185 <T> T getNullable(Class<T> cls); 186 187 /** 188 * Get an optional named dependency potentially returning null. 189 */ 190 <T> T getNullable(Class<T> cls, String name); 191 192 /** 193 * Get an optional dependency potentially returning null for the generic type. 194 */ 195 <T> T getNullable(Type cls); 196 197 /** 198 * Get an optional named dependency potentially returning null for the generic type. 199 */ 200 <T> T getNullable(Type cls, String name); 201 202 /** 203 * Return Provider of T given the type. 204 */ 205 <T> Provider<T> getProvider(Class<T> cls); 206 207 /** 208 * Return Provider of T given the type and name. 209 */ 210 <T> Provider<T> getProvider(Class<T> cls, String name); 211 212 /** 213 * Return Provider of T given the generic type. 214 */ 215 <T> Provider<T> getProvider(Type cls); 216 217 /** 218 * Return Provider of T given the generic type and name. 219 */ 220 <T> Provider<T> getProvider(Type cls, String name); 221 222 /** 223 * Return Provider for a generic interface type. 224 * 225 * @param cls The usual implementation class 226 * @param type The generic interface type 227 */ 228 <T> Provider<T> getProviderFor(Class<?> cls, Type type); 229 230 /** 231 * Get a list of dependencies for the type. 232 */ 233 <T> List<T> list(Class<T> type); 234 235 /** 236 * Get a list of dependencies for the generic type. 237 */ 238 <T> List<T> list(Type type); 239 240 /** 241 * Get a list of dependencies for the type and name. 242 */ 243 <T> List<T> list(Type type, String name); 244 245 /** 246 * Get a set of dependencies for the type. 247 */ 248 <T> Set<T> set(Class<T> type); 249 250 /** 251 * Get a set of dependencies for the generic type. 252 */ 253 <T> Set<T> set(Type type); 254 255 /** 256 * Get a set of dependencies for the type and name. 257 */ 258 <T> Set<T> set(Type type, String name); 259 260 /** 261 * Return a map of dependencies for the type keyed by qualifier name. 262 */ 263 <T> Map<String, T> map(Class<T> type); 264 265 /** 266 * Return a map of dependencies for the generic type keyed by qualifier name. 267 */ 268 <T> Map<String, T> map(Type type); 269 270 /** 271 * Return true if the builder contains the given type. 272 */ 273 boolean contains(Type type); 274 275 /** 276 * Return true if the builder contains the given type. 277 */ 278 boolean contains(String type); 279 280 /** 281 * Return true if the builder contains a bean with the given name. 282 */ 283 boolean containsQualifier(String name); 284 285 /** 286 * Return true if the builder contains the given profile 287 */ 288 boolean containsProfiles(List<String> type); 289 290 /** 291 * Return true if the builder contains all of the given profile 292 */ 293 boolean containsAllProfiles(List<String> type); 294 295 /** 296 * Return the plugin for required properties. 297 */ 298 ConfigPropertyPlugin property(); 299 300 /** 301 * Build and return the bean scope. 302 */ 303 BeanScope build(boolean withShutdownHook, long start); 304 305 /** 306 * Set the current module being wired. 307 */ 308 void currentModule(Class<? extends AvajeModule> currentModule); 309 310 /** 311 * Set the custom scopes defined by the module being wired. 312 */ 313 void currentScopes(String[] scopes); 314}