minglipro 34dccd1895
All checks were successful
Gitea Actions Build / Build (push) Successful in 51s
feat(utils): 添加 AES 加密解密工具类
- 新增 AesUtils 类,提供 AES/GCM 模式的加密解密方法- 更新 .prettierrc配置,将 useTabs 设置为 true
- 重构 Base64Utils 和 Collection 类的代码结构- 简化 ComponentBean 注解定义
2025-08-17 19:12:08 +08:00

249 lines
6.7 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.mingliqiye.utils.bean;
import com.mingliqiye.utils.bean.annotation.ComponentBean;
import com.mingliqiye.utils.bean.annotation.InjectBean;
import java.io.File;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.Enumeration;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* 类似于SpringBoot的Bean管理器
*
* @author MingLiPro
*/
public class Factory {
/**
* 存储所有已注册的Bean实例键为Bean名称值为Bean实例
*/
public static final ConcurrentMap<String, Object> beans =
new ConcurrentHashMap<>();
/**
* 存储按类型查找的Bean实例键为Bean的Class对象值为Bean实例
*/
private static final ConcurrentMap<Class<?>, Object> typeBeans =
new ConcurrentHashMap<>();
/**
* 私有构造函数,防止外部实例化该类
*/
private Factory() {}
/**
* 自动扫描指定类所在包下的所有类并注册为Bean
*
* @param c 指定的类,用于获取其所在的包
* @throws IllegalArgumentException 如果传入的类为null或位于默认包中
*/
public static void autoScan(Class<?> c) {
if (c == null) {
throw new IllegalArgumentException("Class cannot be null");
}
Package pkg = c.getPackage();
if (pkg == null) {
throw new IllegalArgumentException(
"Class is in the default package"
);
}
scan(pkg.getName());
}
/**
* 扫描指定包路径下的所有类文件,并注册其中带有@ComponentBean注解的类为Bean
*
* @param basePackage 要扫描的基础包名
* @throws RuntimeException 如果在扫描过程中发生异常
*/
public static void scan(String basePackage) {
try {
String path = basePackage.replace('.', '/');
ClassLoader classLoader =
Thread.currentThread().getContextClassLoader();
Enumeration<URL> resources = null;
resources = classLoader.getResources(path);
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
File file = new File(resource.toURI());
scanDirectory(file, basePackage);
}
injectDependencies();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 递归扫描目录中的所有类文件并注册符合条件的类为Bean
*
* @param directory 当前要扫描的目录
* @param packageName 当前目录对应的包名
* @throws Exception 如果在扫描或类加载过程中发生异常
*/
private static void scanDirectory(File directory, String packageName)
throws Exception {
File[] files = directory.listFiles();
if (files == null) {
return;
}
for (File file : files) {
if (file.isDirectory()) {
scanDirectory(file, packageName + "." + file.getName());
} else if (file.getName().endsWith(".class")) {
String className =
packageName + '.' + file.getName().replace(".class", "");
registerComponent(Class.forName(className));
}
}
}
/**
* 注册一个带有@ComponentBean注解的类为Bean实例
*
* @param clazz 要注册的类
* @throws Exception 如果在实例化类或处理注解时发生异常
*/
private static void registerComponent(Class<?> clazz) throws Exception {
if (clazz.isAnnotationPresent(ComponentBean.class)) {
ComponentBean component = clazz.getAnnotation(ComponentBean.class);
String name = component.value().isEmpty()
? clazz.getName()
: component.value();
Object instance = clazz.getDeclaredConstructor().newInstance();
beans.put(name, instance);
typeBeans.put(clazz, instance);
for (Class<?> interfaceClass : clazz.getInterfaces()) {
typeBeans.putIfAbsent(interfaceClass, instance);
}
}
}
/**
* 对所有已注册的Bean进行依赖注入处理
*
* @throws Exception 如果在注入过程中发生异常
*/
private static void injectDependencies() throws Exception {
for (Object bean : beans.values()) {
for (Field field : bean.getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(InjectBean.class)) {
InjectBean inject = field.getAnnotation(InjectBean.class);
Object dependency = findDependency(
field.getType(),
inject.value()
);
if (dependency == null) {
throw new IllegalStateException(
"No suitable dependency found for field " +
field.getName() +
" in class " +
bean.getClass().getName()
);
}
field.setAccessible(true);
field.set(bean, dependency);
}
}
}
}
/**
* 根据类型和名称查找对应的依赖实例
*
* @param type 依赖的类型
* @param name 依赖的名称(可为空)
* @return 找到的依赖实例未找到则返回null
*/
private static Object findDependency(Class<?> type, String name) {
if (!name.isEmpty()) {
return beans.get(name);
}
Object dependency = typeBeans.get(type);
if (dependency != null) {
return dependency;
}
for (Class<?> interfaceType : typeBeans.keySet()) {
if (type.isAssignableFrom(interfaceType)) {
return typeBeans.get(interfaceType);
}
}
return null;
}
/**
* 将一个对象添加到Bean容器中使用其类名作为键
*
* @param object 要添加的对象
* @throws RuntimeException 如果在注入依赖时发生异常
*/
public static void add(Object object) {
Class<?> clazz = object.getClass();
String name = clazz.getName();
beans.put(name, object);
typeBeans.put(clazz, object);
try {
injectDependencies();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 将一个对象以指定名称添加到Bean容器中
*
* @param name Bean的名称
* @param object 要添加的对象
* @throws RuntimeException 如果在注入依赖时发生异常
*/
public static void add(String name, Object object) {
beans.put(name, object);
typeBeans.put(object.getClass(), object);
try {
injectDependencies();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 根据类型获取对应的Bean实例
*
* @param objclass Bean的类型
* @param <T> Bean的泛型类型
* @return 对应类型的Bean实例未找到则返回null
*/
public static <T> T get(Class<T> objclass) {
return objclass.cast(typeBeans.get(objclass));
}
/**
* 根据名称和类型获取对应的Bean实例
*
* @param name Bean的名称
* @param objclass Bean的类型
* @param <T> Bean的泛型类型
* @return 对应名称和类型的Bean实例未找到则返回null
*/
public static <T> T get(String name, Class<T> objclass) {
return objclass.cast(beans.get(name));
}
/**
* 根据名称获取对应的Bean实例
*
* @param name Bean的名称
* @return 对应名称的Bean实例未找到则返回null
*/
public static Object get(String name) {
return beans.get(name);
}
}