我们要模仿spring部分功能,1.首先要把扫描路径下的文件获取到 2.把文件下的class变成对象存放在单例池中 3.测试单例池对象方法是否可以执行
1.配置config类
@ComponentScan("com.hxy.service")
public class AppConfig {
}
2.配置解析config的处理类
1)解析单个class 存放成BeanDefinition对象,定义如下
public class BeanDefinition {
private String scope;//是否是单例的
private Class beanClass;
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public Class getBeanClass() {
return beanClass;
}
public void setBeanClass(Class beanClass) {
this.beanClass = beanClass;
}
}
2) AnnotationConfigApplicationContext
第一步是扫描文件 方法如下:
主要通过classloader获取到路径下面的文件,然后通过把文件名截取成.的形式,通过classload.loadclass装载成calss对象
/**
* 加载路径下面所有的class
* @param configClass
* @return
*/
private List<Class> scan(Class configClass) {
List<Class> classList = new ArrayList<>();
ComponentScan componentScan = (ComponentScan) configClass.getAnnotation(ComponentScan.class);
String scanPath = componentScan.value();
scanPath = scanPath.replace(".","/");
ClassLoader classLoader = AnnotationConfigApplicationContext.class.getClassLoader();
URL resource = classLoader.getResource(scanPath);
File file = new File(resource.getFile());
File[] files = file.listFiles();
for (File f : files) {
String absolutePath = f.getAbsolutePath();
// E:\git\saas_common\neetyT\myspring\target\classes\com\hxy\service\AService.class
//E:\git\saas_common\neetyT\myspring\target\classes\com\hxy\service\Bservice.class
absolutePath = absolutePath.substring(absolutePath.lastIndexOf("com"), absolutePath.indexOf(".class"));
absolutePath = absolutePath.replace("\\",".");
// System.out.println(absolutePath);
Class<?> clazz = null;
try {
clazz = classLoader.loadClass(absolutePath);
classList.add(clazz);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return classList;
}
第二步是通过class对象解析成object对象主要通过无参构造生成对象
public AnnotationConfigApplicationContext(Class configClass) {
List<Class> classList = scan(configClass);
for (Class clz : classList) {
if (clz.isAnnotationPresent(Component.class)) {
Component component = (Component) clz.getAnnotation(Component.class);
String beanName = component.value();
BeanDefinition beanDefinition = new BeanDefinition();
beanDefinition.setBeanClass(clz);
beanDefinitionMap.put(beanName, beanDefinition);
}
}
for (String beanName : beanDefinitionMap.keySet()) {
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
// 生成对象
Object bean = createBean(beanName, beanDefinition);
singletonObjects.put(beanName,bean);
}
}
private Object createBean(String beanName, BeanDefinition beanDefinition) {
Class beanClass = beanDefinition.getBeanClass();
Object newInstance = null;
try {
// 无参构造 生成对象
newInstance = beanClass.getDeclaredConstructor().newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return newInstance;
}
3.测试
结果是
自此简单的spring扫描文件生成对象成功
第二篇解决循环依赖注入 https://blog.csdn.net/qq_28852755/article/details/108716819