Last active
June 5, 2024 06:51
-
-
Save IdanKoblik/1f4b6427f27fe157007489b970bd4c29 to your computer and use it in GitHub Desktop.
DynamicInstantiator a utility class that provides a way to dynamically instantiate
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import lombok.extern.log4j.Log4j2; | |
import com.google.common.reflect.ClassPath; | |
import java.util.function.Consumer; | |
/** | |
* The DynamicInstantiator class is a utility class that provides a way to dynamically instantiate | |
* and register classes that implement a specific base class. | |
*/ | |
@Log4J2 | |
public class DynamicInstantiator { | |
private static DynamicInstantiator instance; | |
/** | |
* Returns the singleton instance of the DynamicInstantiator class. | |
* | |
* @return The instance of the DynamicInstantiator class. | |
*/ | |
public static DynamicInstantiator getInstance() { | |
return instance == null ? (instance = new DynamicInstantiator()) : instance; | |
} | |
/** | |
* Dynamically instantiates and registers classes that extend or implement the specified baseClass | |
* within the given packageName. For each found class, the provided action is executed with the | |
* instantiated object as a parameter. | |
* | |
* @param packageName The package name to scan for classes. | |
* @param baseClass The base class that the desired classes should extend or implement. | |
* @param action The action to perform on each found class, represented as a Consumer lambda. | |
* @param <T> The type parameter for the baseClass. | |
*/ | |
public <T> void register(String packageName, Class<T> baseClass, Consumer<T> action) { | |
ClassLoader classLoader = getClass().getClassLoader(); | |
ClassPath classPath; | |
try { | |
classPath = ClassPath.from(classLoader); | |
} catch (Exception e) { | |
throw new RuntimeException(e); | |
} | |
for (ClassPath.ClassInfo classInfo : classPath.getTopLevelClassesRecursive(packageName)) { | |
try { | |
Class<?> clazz = Class.forName(classInfo.getName(), true, classLoader); | |
if (baseClass.isAssignableFrom(clazz) && !clazz.equals(baseClass)) | |
action.accept(clazz.asSubclass(baseClass).getDeclaredConstructor().newInstance()); | |
} catch (Throwable e) { | |
log.error(e.getMessage()); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment