Injector.java
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.di;
import java.lang.annotation.Annotation;
import java.util.function.Supplier;
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.di.impl.InjectorImpl;
/**
* The main entry point for Maven's dependency injection framework.
* <p>
* The Injector manages the creation and injection of objects within the Maven build process.
* It provides both a builder API for configuring the injection behavior and methods for
* accessing and injecting beans.
* <p>
* Example usage:
* <pre>
* Injector injector = Injector.create()
* .discover(getClass().getClassLoader())
* .bindInstance(Configuration.class, config);
*
* MyService service = injector.getInstance(MyService.class);
* </pre>
*
* @since 4.0.0
*/
public interface Injector {
/**
* Creates a new Injector instance with default settings.
*
* @return a new Injector instance
*/
@Nonnull
static Injector create() {
return new InjectorImpl();
}
/**
* Configures the injector to discover injectable components from the specified ClassLoader.
* <p>
* This method scans for classes annotated with injection-related annotations and
* automatically registers them with the injector.
*
* @param classLoader the ClassLoader to scan for injectable components
* @return this injector instance for method chaining
* @throws NullPointerException if classLoader is null
*/
@Nonnull
Injector discover(@Nonnull ClassLoader classLoader);
/**
* Binds a scope annotation to its implementation.
* <p>
* This allows custom scopes to be registered with the injector. The scope annotation
* must be annotated with {@link org.apache.maven.api.di.Scope}.
*
* @param scopeAnnotation the annotation class that defines the scope
* @param scope the scope implementation
* @return this injector instance for method chaining
* @throws NullPointerException if either parameter is null
*/
@Nonnull
Injector bindScope(@Nonnull Class<? extends Annotation> scopeAnnotation, @Nonnull Scope scope);
/**
* Binds a scope annotation to a supplier that creates scope implementations.
* <p>
* Similar to {@link #bindScope(Class, Scope)} but allows lazy creation of scope
* implementations.
*
* @param scopeAnnotation the annotation class that defines the scope
* @param scope supplier that creates scope implementations
* @return this injector instance for method chaining
* @throws NullPointerException if either parameter is null
*/
@Nonnull
Injector bindScope(@Nonnull Class<? extends Annotation> scopeAnnotation, @Nonnull Supplier<Scope> scope);
/**
* Registers a class for implicit binding.
* <p>
* Implicit bindings allow the injector to create instances of classes without
* explicit binding definitions. The class must have appropriate injection annotations.
*
* @param cls the class to register for implicit binding
* @return this injector instance for method chaining
* @throws NullPointerException if cls is null
*/
@Nonnull
Injector bindImplicit(@Nonnull Class<?> cls);
/**
* Binds a specific instance to a class type.
* <p>
* This method allows pre-created instances to be used for injection instead of
* having the injector create new instances.
*
* @param <T> the type of the instance
* @param cls the class to bind to
* @param instance the instance to use for injection
* @return this injector instance for method chaining
* @throws NullPointerException if either parameter is null
*/
@Nonnull
<T> Injector bindInstance(@Nonnull Class<T> cls, @Nonnull T instance);
/**
* Binds a specific instance supplier to a class type.
* <p>
* This method allows pre-created instances to be used for injection instead of
* having the injector create new instances.
*
* @param <T> the type of the instance
* @param cls the class to bind to
* @param supplier the supplier to use for injection
* @return this injector instance for method chaining
* @throws NullPointerException if either parameter is null
*/
@Nonnull
<T> Injector bindSupplier(@Nonnull Class<T> cls, @Nonnull Supplier<T> supplier);
/**
* Performs field and method injection on an existing instance.
* <p>
* This method will inject dependencies into annotated fields and methods of
* the provided instance but will not create a new instance.
*
* @param <T> the type of the instance
* @param instance the instance to inject dependencies into
* @throws NullPointerException if instance is null
*/
<T> void injectInstance(@Nonnull T instance);
/**
* Retrieves or creates an instance of the specified type.
*
* @param <T> the type to retrieve
* @param key the class representing the type to retrieve
* @return an instance of the requested type
* @throws NullPointerException if key is null
* @throws IllegalStateException if the type cannot be provided
*/
@Nonnull
<T> T getInstance(@Nonnull Class<T> key);
/**
* Retrieves or creates an instance for the specified key.
* <p>
* This method allows retrieval of instances with specific qualifiers or
* generic type parameters.
*
* @param <T> the type to retrieve
* @param key the key identifying the instance to retrieve
* @return an instance matching the requested key
* @throws NullPointerException if key is null
* @throws IllegalStateException if the type cannot be provided
*/
@Nonnull
<T> T getInstance(@Nonnull Key<T> key);
/**
* Disposes this Injector, clearing all internal state (bindings, caches, scopes, etc.).
* After calling this, the Injector should not be used again.
* @since 4.1
*/
default void dispose() {
// delegate to the implementation
if (this instanceof InjectorImpl) {
((InjectorImpl) this).dispose();
}
}
}