手写简易spring
`package com.spring.utils;
import com.spring.BeanDefinition;
import com.spring.inteface.Autowried;
import com.spring.inteface.Component;
import com.spring.inteface.ComponentScan;
import com.spring.inteface.Scope;
import com.spring.service.UserService;
import com.sun.security.jgss.GSSUtil;
import java.beans.Introspector;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class ApplicationContext {
private Class aClass; //存储 类类型
private Map<String,BeanDefinition> beanDefinitionMap = new HashMap<>();
private Map<String,Object> singletonDefinitions = new HashMap<>(); //单例池
public ApplicationContext(Class aClass){
this.aClass = aClass;
// 扫描bean
scan(aClass);
// 扫描完了该创建bean spring也是如此在构造器一开始就创建bean
// 判断是否是单例的
for (Map.Entry<String, BeanDefinition> beanDefinitionSet : beanDefinitionMap.entrySet()) {
String beanName = beanDefinitionSet.getKey();
BeanDefinition beanDefinition = beanDefinitionSet.getValue(); //beanDefinition
if (beanDefinition.getScope().equals("singleton")){
Object bean = createBean(beanName, beanDefinition);
singletonDefinitions.put(beanName,bean); //存到单例池中
}
}
}
private Object createBean(String beanName,BeanDefinition beanDefinition){
// 这里简单只要用反射就行
Class aClass1 = beanDefinition.getaClassType();
Object o = null;
try {
o = aClass1.getConstructor().newInstance();
// 2.1 处理依赖注入的问题 寻找字段中是否有AutoWried注解
for (Field declaredField : aClass1.getDeclaredFields()) {
// 判断是否有Autowired注解
if (declaredField.isAnnotationPresent(Autowried.class)) {
// 这里注入的是orderWried类型简单点就根据字段名字获取,默认注解注入是单例的
declaredField.setAccessible(true);
declaredField.set(o,getBean(declaredField.getName()));
}
}
} 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);
}
return o;
}
public void scan(Class aClass){
// 1. 第一步判断传入的类是否有ComponentScan注解
if (aClass.isAnnotationPresent(ComponentScan.class)){
//1.2 实现了抽取出注解value值
ComponentScan componentScan = (ComponentScan) aClass.getAnnotation(ComponentScan.class);
String path = componentScan.value(); // com.spring.service
//1.3 注意这里 只是取到扫描的包,需要编译后在本机的的具体位置给classload加载 以保证真是本机地址读取包下的calss类
String replacePath = path.replace(".", "/"); //com/spring/service
//1.4 通过类加载器加载这个地址在本机的位置
ClassLoader classLoader = aClass.getClassLoader();
URL resource = classLoader.getResource(replacePath); //本机地址 file:/E:/code/spring/target/classes/com/spring/service
//1.5 分装成file
String file = resource.getFile();
File files = new File(file);
//1.5.1 判断files 是一个文件夹
if (files.isDirectory()){
// 1.5.2 遍历得到目录下的文件
File[] files1 = files.listFiles();
for (File file1 : files1) {
//1.5.3 取到每个文件的绝对路径
String absolutePath = file1.getAbsolutePath(); //E:\code\spring\target\classes\com\spring\service\UserService.class
absolutePath = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class"));
absolutePath = absolutePath.replace("\\", ".");
//1.5.4 判断这个类是否加了Component注解有注解才进行下一步,所以就需要类加载器加载class文件变成类
try {
Class<?> loadedClass = classLoader.loadClass(absolutePath);
// 1.5.5 使用beanDefinition判断是否实现
if (loadedClass.isAnnotationPresent(Component.class)) {
Component annotation = loadedClass.getAnnotation(Component.class);
String beanName = annotation.value();// 拿到Component的bean的名称
if ("".equals(beanName)) {
// 自动生成首字母小写
beanName = Introspector.decapitalize(loadedClass.getSimpleName());
}
// Bean 需要封装起来
BeanDefinition beanDefinition = new BeanDefinition();
beanDefinition.setaClassType(loadedClass);
//1.5.6 判断是否是单例
if (loadedClass.isAnnotationPresent(Scope.class)){
Scope scope = loadedClass.getAnnotation(Scope.class);
String value = scope.value();
beanDefinition.setScope(value);
}else {
// 默认单例
beanDefinition.setScope("singleton");
}
//存到map中
beanDefinitionMap.put(beanName,beanDefinition);
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
}
}
/**
* 这里返回bean实例
* @param beanName
* @return
*/
public Object getBean(String beanName){
// 首先判断是否在已扫描的存入map中 不存在抛出异常
if (!beanDefinitionMap.containsKey(beanName)){
throw new NullPointerException();
}
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName); //获取beanDefinition
// 判断是否单例
if (beanDefinition.getScope().equals("singleton")) {
// 如果是单例就从单例池map中取出
Object singleton = singletonDefinitions.get(beanName);
// 2.2 这里有个问题如果orderService是原型的那么在单例池就获取不到,我们就要创建bean保存到单例池中
if (singleton == null){
Object bean = createBean(beanName,beanDefinition);
singletonDefinitions.put(beanName,bean);
}
return singleton;
}else {
// 原型 每次都创建
Object protoType = createBean(beanName, beanDefinition);
return protoType;
}
}
}
`
实现了spring的依赖注入和还未实现inilizingBean和BeanPostProcessor不过都是简单了,aop实在BeanPostProcessor的初始化方法后那个方法执行的可以使用CJLIB或者动态代理,动态代理需要父接口,CJLIB只需要继承被代理对象就可