实现IOC容器,依赖注入
import java.io.File;
import java.io.FileFilter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* 简易在简易 IOC 容器
*/
public class YzxIoc {
public static void main(String[] args) {
iocAndYlZhuRu("com.swordfinger");
}
public static void iocAndYlZhuRu(String packName) {
if (null == packName) throw new RuntimeException("包路径不存在");
Set<Class<?>> classSet = new HashSet<>();
/**
* 1、扫描包下的所有class文件
*/
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
URL url = contextClassLoader.getResource(packName.replace(".", File.separator));
if (null == url) throw new RuntimeException("包路径错误");
if (!url.getProtocol().startsWith("file")) throw new RuntimeException("仅支持文件路径");
File file = new File(url.getPath());
if (!file.isDirectory()) throw new RuntimeException("目录非包名");
//此处可替换成递归操作。终止条件:不存在文件夹退出
File[] files = file.listFiles(new FileFilter() {
@Override
public boolean accept(File aaa) {
if (aaa.isDirectory()) return true;
if (aaa.getAbsolutePath().endsWith(".class")) {
//根据class文件生成Class对象
Class<?> aClass = getClass(aaa.getAbsolutePath());
classSet.add(aClass);
}
return false;
}
private Class<?> getClass(String absolutePath) {
System.err.println("absolutePath:" + absolutePath);
//截取
String className = absolutePath.substring(absolutePath.indexOf(packName));
className = className.substring(0, className.lastIndexOf("."));
/**
* 2、通过反射机制获取对应的Class对象并加入到classSet里
*/
try {
Class<?> aClass = Class.forName(className);
return aClass;
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
});
Arrays.stream(files).forEach(op -> {
if (op.isDirectory()) {
File[] listFiles = op.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if (pathname.isDirectory()) return true;
if (pathname.getAbsolutePath().endsWith(".class")) {
//根据class文件生成Class对象
Class<?> aClass = getClass(pathname.getAbsolutePath());
classSet.add(aClass);
}
return false;
}
private Class<?> getClass(String absolutePath) {
System.err.println("absolutePath:" + absolutePath);
absolutePath = absolutePath.replace(File.separator, ".");
//截取
String className = absolutePath.substring(absolutePath.indexOf(packName));
className = className.substring(0, className.lastIndexOf("."));
/**
* 2、通过反射机制获取对应的Class对象并加入到classSet里
*/
try {
Class<?> aClass = Class.forName(className);
return aClass;
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
});
Arrays.stream(listFiles).forEach(ccc -> {
if (ccc.isDirectory()) {
ccc.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if (pathname.isDirectory()) return true;
if (pathname.getAbsolutePath().endsWith(".class")) {
//根据class文件生成Class对象
Class<?> aClass = getClass(pathname.getAbsolutePath());
classSet.add(aClass);
}
return false;
}
private Class<?> getClass(String absolutePath) {
System.err.println("absolutePath:" + absolutePath);
absolutePath = absolutePath.replace(File.separator, ".");
//截取
String className = absolutePath.substring(absolutePath.indexOf(packName));
className = className.substring(0, className.lastIndexOf("."));
/**
* 2、通过反射机制获取对应的Class对象并加入到classSet里
*/
try {
Class<?> aClass = Class.forName(className);
return aClass;
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
});
}
});
}
});
System.err.println(classSet);
/**
* 2、过滤出特定注解的class对象。加载Bean
*/
List<Class<? extends Annotation>> annotationData =
Arrays.asList(YouController.class, YouService.class, YouRepository.class, YouComponent.class);
Set<Class<?>> filterSet = new HashSet<>();
classSet.stream().forEach(aClass -> {
annotationData.stream().forEach(annotation -> {
if (aClass.isAnnotationPresent(annotation)) {
filterSet.add(aClass);
}
});
});
//容器
Map<Class<?>, Object> iocMap = new ConcurrentHashMap<>();
/**
* 3、获取class对象对应的实例
*/
filterSet.stream().forEach(op -> {
try {
Object o = op.newInstance();
/**
* 4、放入容器中
*/
iocMap.put(op, o);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
System.err.println(iocMap);
/**
* 5、依赖注入---获取容器中所有Class对象
*/
Set<Class<?>> keySetData = iocMap.keySet();
/**
* 6、获取每个Class对象的成员变量
*/
keySetData.stream().forEach(op -> {
//获取所有成员变量
Field[] declaredFields = op.getDeclaredFields();
Arrays.stream(declaredFields).forEach(field -> {
/**
* 7、 如果存在注解实例,则获取成员变量的类型
*/
if (field.isAnnotationPresent(YouAutowired.class)) {
//获取注解值
YouAutowired annotation = field.getAnnotation(YouAutowired.class);
String value = annotation.value();
//获取成员变量的类型
Class<?> type = field.getType();
//根据成员变量类型获取在容器的实例
Object o = iocMap.get(type);
if (null == o) {
//是接口
Class<?> aClass = classSet.stream().filter(hb -> hb.getSimpleName().equals(value)).findAny().orElse(null);
o = iocMap.get(aClass);
}
/**
* 8、注入成员变量。结束
*/
try {
//获取类实例
Object o1 = iocMap.get(op);
field.setAccessible(true);
field.set(o1, o);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
});
});
System.err.println(iocMap);
}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface YouComponent {
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface YouController {
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface YouRepository {
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface YouService {
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface YouAutowired {
String value() default "";
}
@Getter
@YouController
public class OrderController {
@YouAutowired(value = "OrderServiceImpl")
private OrderService orderService;
}
public interface OrderService {
String queryById(String id);
}
@YouService
public class HndlerServiceImpl implements OrderService {
@Override
public String queryById(String id) {
return null;
}
}
@YouService
public class OrderServiceImpl implements OrderService {
@YouAutowired
private OrderDao orderDao;
@Override
public String queryById(String id) {
return orderDao.getOrderById(id);
}
}
@YouRepository
public class OrderDao {
public String getOrderById(String id) {
return "dao:" + id;
}
}