Merge pull request 'a' (#1) from dev into master
All checks were successful
Gitea Actions Build / Build (push) Successful in 55s

Reviewed-on: #1
This commit is contained in:
Armamem0t 2025-07-11 13:26:30 +08:00 committed by git.mingliqiye.com
commit def4a76f79
Signed by: git.mingliqiye.com
GPG Key ID: F810443113074559
6 changed files with 216 additions and 15 deletions

1
.gitignore vendored
View File

@ -46,4 +46,5 @@ log
.idea
node_modules
pnpm-lock.yaml
package-lock.json

View File

@ -1,5 +1,5 @@
GROUPSID=com.mingliqiye
ARTIFACTID=socket-utilts
ARTIFACTID=instance-factory
VERSIONS=1.0.1
MAINCLASS=com.mingliqiye.Main
MAINCLASS=com.mingliqiye.bean.Factory
JDKVERSIONS=1.8

View File

@ -1,13 +0,0 @@
package com.mingliqiye;
public class Main {
/**
* @param args []
*/
public static void main(String[] args) {
System.out.print("Hello and welcome!");
for (int i = 1; i <= 5; i++) {
System.out.println("i = " + i);
}
}
}

View File

@ -0,0 +1,9 @@
package com.mingliqiye.bean;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {
String value() default "";
}

View File

@ -0,0 +1,195 @@
package com.mingliqiye.bean;
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;
public class Factory {
public static final ConcurrentMap<String, Object> beans =
new ConcurrentHashMap<>();
private static final ConcurrentMap<Class<?>, Object> typeBeans =
new ConcurrentHashMap<>();
private Factory() {}
/**
* 自动扫描注解
* @param c 包名所在的类
*/
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());
}
/**
* 扫描注解
* @param basePackage 包名
*/
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);
}
}
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));
}
}
}
private static void registerComponent(Class<?> clazz) throws Exception {
if (clazz.isAnnotationPresent(Component.class)) {
Component component = clazz.getAnnotation(Component.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);
}
}
}
private static void injectDependencies() throws Exception {
for (Object bean : beans.values()) {
for (Field field : bean.getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(Inject.class)) {
Inject inject = field.getAnnotation(Inject.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);
}
}
}
}
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;
}
/**
* 添加一个实例
* @param object 示例对象
*/
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);
}
}
/**
* 添加一个实例
* @param name 实例名
* @param object 实例
*/
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);
}
}
/**
* 获取实例
* @param objclass 实例类
* @return T 实例
* @param <T>
*/
public static <T> T get(Class<T> objclass) {
return objclass.cast(typeBeans.get(objclass));
}
/**
* 获取实例
* @param name 实例名
* @param objclass 实例类
* @return T 实例
* @param <T>
*/
public static <T> T get(String name, Class<T> objclass) {
return objclass.cast(beans.get(name));
}
/**
* 获取实例
* @param name 实例名
* @return Object 实例
*/
public static Object get(String name) {
return beans.get(name);
}
public static void main(String[] args) {}
}

View File

@ -0,0 +1,9 @@
package com.mingliqiye.bean;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Inject {
String value() default "";
}