1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.maven.di;
20
21 import java.lang.annotation.Annotation;
22 import java.util.function.Supplier;
23
24 import org.apache.maven.api.annotations.Nonnull;
25 import org.apache.maven.di.impl.InjectorImpl;
26
27 /**
28 * The main entry point for Maven's dependency injection framework.
29 * <p>
30 * The Injector manages the creation and injection of objects within the Maven build process.
31 * It provides both a builder API for configuring the injection behavior and methods for
32 * accessing and injecting beans.
33 * <p>
34 * Example usage:
35 * <pre>
36 * Injector injector = Injector.create()
37 * .discover(getClass().getClassLoader())
38 * .bindInstance(Configuration.class, config);
39 *
40 * MyService service = injector.getInstance(MyService.class);
41 * </pre>
42 *
43 * @since 4.0.0
44 */
45 public interface Injector {
46
47 /**
48 * Creates a new Injector instance with default settings.
49 *
50 * @return a new Injector instance
51 */
52 @Nonnull
53 static Injector create() {
54 return new InjectorImpl();
55 }
56
57 /**
58 * Configures the injector to discover injectable components from the specified ClassLoader.
59 * <p>
60 * This method scans for classes annotated with injection-related annotations and
61 * automatically registers them with the injector.
62 *
63 * @param classLoader the ClassLoader to scan for injectable components
64 * @return this injector instance for method chaining
65 * @throws NullPointerException if classLoader is null
66 */
67 @Nonnull
68 Injector discover(@Nonnull ClassLoader classLoader);
69
70 /**
71 * Binds a scope annotation to its implementation.
72 * <p>
73 * This allows custom scopes to be registered with the injector. The scope annotation
74 * must be annotated with {@link org.apache.maven.api.di.Scope}.
75 *
76 * @param scopeAnnotation the annotation class that defines the scope
77 * @param scope the scope implementation
78 * @return this injector instance for method chaining
79 * @throws NullPointerException if either parameter is null
80 */
81 @Nonnull
82 Injector bindScope(@Nonnull Class<? extends Annotation> scopeAnnotation, @Nonnull Scope scope);
83
84 /**
85 * Binds a scope annotation to a supplier that creates scope implementations.
86 * <p>
87 * Similar to {@link #bindScope(Class, Scope)} but allows lazy creation of scope
88 * implementations.
89 *
90 * @param scopeAnnotation the annotation class that defines the scope
91 * @param scope supplier that creates scope implementations
92 * @return this injector instance for method chaining
93 * @throws NullPointerException if either parameter is null
94 */
95 @Nonnull
96 Injector bindScope(@Nonnull Class<? extends Annotation> scopeAnnotation, @Nonnull Supplier<Scope> scope);
97
98 /**
99 * Registers a class for implicit binding.
100 * <p>
101 * Implicit bindings allow the injector to create instances of classes without
102 * explicit binding definitions. The class must have appropriate injection annotations.
103 *
104 * @param cls the class to register for implicit binding
105 * @return this injector instance for method chaining
106 * @throws NullPointerException if cls is null
107 */
108 @Nonnull
109 Injector bindImplicit(@Nonnull Class<?> cls);
110
111 /**
112 * Binds a specific instance to a class type.
113 * <p>
114 * This method allows pre-created instances to be used for injection instead of
115 * having the injector create new instances.
116 *
117 * @param <T> the type of the instance
118 * @param cls the class to bind to
119 * @param instance the instance to use for injection
120 * @return this injector instance for method chaining
121 * @throws NullPointerException if either parameter is null
122 */
123 @Nonnull
124 <T> Injector bindInstance(@Nonnull Class<T> cls, @Nonnull T instance);
125
126 /**
127 * Performs field and method injection on an existing instance.
128 * <p>
129 * This method will inject dependencies into annotated fields and methods of
130 * the provided instance but will not create a new instance.
131 *
132 * @param <T> the type of the instance
133 * @param instance the instance to inject dependencies into
134 * @throws NullPointerException if instance is null
135 */
136 <T> void injectInstance(@Nonnull T instance);
137
138 /**
139 * Retrieves or creates an instance of the specified type.
140 *
141 * @param <T> the type to retrieve
142 * @param key the class representing the type to retrieve
143 * @return an instance of the requested type
144 * @throws NullPointerException if key is null
145 * @throws IllegalStateException if the type cannot be provided
146 */
147 @Nonnull
148 <T> T getInstance(@Nonnull Class<T> key);
149
150 /**
151 * Retrieves or creates an instance for the specified key.
152 * <p>
153 * This method allows retrieval of instances with specific qualifiers or
154 * generic type parameters.
155 *
156 * @param <T> the type to retrieve
157 * @param key the key identifying the instance to retrieve
158 * @return an instance matching the requested key
159 * @throws NullPointerException if key is null
160 * @throws IllegalStateException if the type cannot be provided
161 */
162 @Nonnull
163 <T> T getInstance(@Nonnull Key<T> key);
164 }