DIComponent.java
package space.sunqian.fs.di;
import space.sunqian.annotation.Immutable;
import space.sunqian.annotation.Nonnull;
import space.sunqian.annotation.Nullable;
import space.sunqian.fs.invoke.InvocationException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.List;
/**
* Represents component of {@link DIContainer}, consisting of a type and a singleton instance of that type.
* <p>
* {@link DIComponent} is distinguished by {@link #type()}, two {@link DIComponent} instances with same raw class but
* different generic type parameters are considered as two different components.
*
* @author sunqian
*/
public interface DIComponent {
/**
* Returns the default resolver for {@link DIComponent}.
*
* @return the default resolver for {@link DIComponent}
*/
static @Nonnull Resolver defaultResolver() {
return DIContainerImpl.Resolver.INST;
}
/**
* Returns the default field setter for {@link DIComponent}.
*
* @return the default field setter for {@link DIComponent}
*/
static @Nonnull FieldSetter defaultFieldSetter() {
return DIContainerImpl.FieldSetter.INST;
}
/**
* Returns the type of this component.
*
* @return the type of this component
*/
@Nonnull
Type type();
/**
* Returns the singleton instance of this component's type.
*
* @return the singleton instance of this component's type
*/
@Nonnull
Object instance();
/**
* Returns whether this component is directly owned by the current container, rather than inherited from parent
* containers.
*
* @return {@code true} if this component is directly owned by the current container, rather than inherited from
* parent containers; {@code false} otherwise
*/
boolean isLocal();
/**
* Returns the dependencies of this component.
*
* @return the dependencies of this component
*/
@Nonnull
@Immutable
List<@Nonnull DIComponent> dependencies();
/**
* Returns the post-construct method of this component.
*
* @return the post-construct method of this component
*/
@Nullable
Method postConstructMethod();
/**
* Returns the dependencies of this component for post-construct method.
*
* @return the dependencies of this component for post-construct method
*/
@Nonnull
@Immutable
List<@Nonnull DIComponent> postConstructDependencies();
/**
* Invokes the post-construct method of this component if the post-construct method is not {@code null}, otherwise
* this method has no effect. Note this method ignore the dependencies of the post-construct method.
*
* @throws InvocationException for wrapping any error during execution of the method
*/
void postConstruct() throws InvocationException;
/**
* Returns whether this component is initialized, the post-construct method has also been executed normally.
*
* @return {@code true} if this component is initialized; {@code false} otherwise
*/
boolean isInitialized();
/**
* Returns the pre-destroy method of this component.
*
* @return the pre-destroy method of this component
*/
@Nullable
Method preDestroyMethod();
/**
* Returns the dependencies of this component for pre-destroy method.
*
* @return the dependencies of this component for pre-destroy method
*/
@Nonnull
@Immutable
List<@Nonnull DIComponent> preDestroyDependencies();
/**
* Invokes the pre-destroy method of this component if the pre-destroy method is not {@code null}, otherwise this
* method has no effect. Note this method ignore the dependencies of the pre-destroy method.
*
* @throws InvocationException for wrapping any error during execution of the method
*/
void preDestroy() throws InvocationException;
/**
* Returns whether this component is destroyed, the pre-destroy method has also been executed normally.
*
* @return {@code true} if this component is destroyed; {@code false} otherwise
*/
boolean isDestroyed();
/**
* Represents resolver for {@link DIComponent}.
*/
interface Resolver {
/**
* Resolves the descriptor of the component.
*
* @param type the type of the component
* @param componentAnnotations The class name of the annotations to mark the component, such as:
* {@code javax.annotation.Resource}, {@code jakarta.annotation.Resource}.
* @param postConstructAnnotations The class name of the annotations to mark the post-construct method, such as:
* {@code javax.annotation.PostConstruct},
* {@code jakarta.annotation.PostConstruct}.
* @param preDestroyAnnotations The class name of the annotations to mark the pre-destroy method, such as:
* {@code javax.annotation.PreDestroy}, {@code jakarta.annotation.PreDestroy}.
* @return the descriptor of the component
* @throws Exception for any error during resolving
*/
@Nonnull
Descriptor resolve(
@Nonnull Type type,
@Nonnull Collection<@Nonnull String> componentAnnotations,
@Nonnull Collection<@Nonnull String> postConstructAnnotations,
@Nonnull Collection<@Nonnull String> preDestroyAnnotations
) throws Exception;
}
/**
* Represents descriptor of component type.
*/
interface Descriptor {
/**
* Returns the type of the component.
*
* @return the type of the component
*/
@Nonnull
Type type();
/**
* Returns the raw class of the component.
*
* @return the raw class of the component
*/
@Nonnull
Class<?> rawClass();
/**
* Returns the post-construct method of the component, may be {@code null} if there is no post-construct
* method.
*
* @return the post-construct method of the component, may be {@code null} if there is no post-construct method
*/
@Nullable
Method postConstructMethod();
/**
* Returns the pre-destroy method of the component, may be {@code null} if there is no pre-destroy method.
*
* @return the pre-destroy method of the component, may be {@code null} if there is no pre-destroy method
*/
@Nullable
Method preDestroyMethod();
/**
* Returns the dependency fields of the component.
*
* @return the dependency fields of the component
*/
@Nonnull
@Immutable
List<@Nonnull Field> dependencyFields();
}
/**
* Represents setter for dependency field.
*/
interface FieldSetter {
/**
* Sets the value to the dependency field.
*
* @param field the dependency field
* @param owner the owner instance of the dependency field
* @param value the value to be set
* @throws Exception for any error during setting
*/
void set(@Nonnull Field field, @Nonnull Object owner, @Nonnull Object value) throws Exception;
}
}