package com.example.ioc.spring;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class SpringApplicationContext {
private Class classContext;
//初始化一个单例池
private ConcurrentHashMap<String, Object> singletonObject = new ConcurrentHashMap<>();
//初始化beanDefinition集合,用于存放各个bean对象的信息
private ConcurrentHashMap<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
public SpringApplicationContext(Class classContext) {
this.classContext = classContext;
//扫描包路径方法
scan(classContext);
//遍历beanDefinitionMap集合,得到beanDefinition对象
for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
//获取beanDefinition集合中的bean名称
String beanName = entry.getKey();
//通过beanName获取对象
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
//将对象放入单例池中
if (beanDefinition.getScope().equals("singleton")) {
Object bean = createBean(beanDefinition);
singletonObject.put(beanName, bean);
}
}
}
public Object createBean(BeanDefinition beanDefinition) {
Class clazz = beanDefinition.getClazz();
try {
Object instance = clazz.getDeclaredConstructor().newInstance();
return instance;
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
private void scan(Class classContext) {
//判断该类上是否存在ComponentScan注解
ComponentScan annotation = (ComponentScan) classContext.getAnnotation(ComponentScan.class);
//获取注解上的内容
String path = annotation.value();
//将路径符号进行转义
String replace = path.replaceAll("\\.", "/");
//通过类加载获取资源路径
ClassLoader classLoader = SpringApplicationContext.class.getClassLoader();
URL resource = classLoader.getResource(replace);
//将资源路径放在创建的文件当中
File file = new File(resource.getFile());
//判断是否为文件
if (file.isDirectory()) {
//将所有文件放入一个数组
File[] files = file.listFiles();
//将数组中的文件遍历
for (File f : files) {
String fileName = f.getAbsolutePath();
//判断文件路径是否为.class结尾
if (fileName.endsWith(".class")) {
//对文件的路径进行截取
fileName = fileName.substring(fileName.indexOf("com"), fileName.indexOf(".class"));
//windows系统路径
String className = fileName.replace("\\", ".");
//mac系统路径
//String className = fileName.replace("/", ".");
//System.out.println(className);
try {
//通过类包名获取类的字节码文件
Class<?> aClass = classLoader.loadClass(className);
//判断该类上是否有Component注解
boolean annotationPresent = aClass.isAnnotationPresent(Component.class);
//有该注解。表示这是一个bean
if (annotationPresent) {
//获取当前类上面Component注解中的值
Component annotations = aClass.getDeclaredAnnotation(Component.class);
//获取注解中的值
String beanName = annotations.value();
//创建BeanDefinition对象,对bean的定义
BeanDefinition beanDefinition = new BeanDefinition();
beanDefinition.setClazz(aClass);
//判断该类上面是否有Scope注解
if (aClass.isAnnotationPresent(Scope.class)) {
//获取这个注解
Scope scope = aClass.getDeclaredAnnotation(Scope.class);
beanDefinition.setScope(scope.value());
} else {
beanDefinition.setScope("singleton");
}
beanDefinitionMap.put(beanName, beanDefinition);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
}
public Object getBean(String beanName) {
//判断bean定义的集合中是否存在传入的bean名字
if (beanDefinitionMap.containsKey(beanName)) {
//有,就获取该数据
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if (beanDefinition.getScope().equals("singleton")) {
//从单例池中取出数据
Object o = singletonObject.get(beanName);
return o;
} else {
Object bean = createBean(beanDefinition);
return bean;
}
} else {
throw new RuntimeException("有误");
}
}
public void test() {
System.out.println("手写Spring实现");
}
}
Spring底层实现过程+仿照源码手写
最新推荐文章于 2024-10-16 10:11:07 发布