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