- 通过手写模拟,了解Spring的底层源码启动过程
- 通过手写模拟,了解BeanDefinition、BeanPostProcessor的概念
- 通过手写模拟,了解Spring解析配置类等底层源码工作流程
- 通过手写模拟,了解依赖注入,Aware回调等底层源码工作流程
- 通过手写模拟,了解Spring AOP的底层源码工作流程
1.测试类:
package laoyang;
import laoyang.Service.UserService;
import spring.LaoyangApplicationContext;
/**
* @author:Kevin
* @create: 2023-09-08 20:49
* @Description: 老杨spring手写spring底层模拟
*/
public class Test {
public static void main(String[] args) {
/**
* 创建核心配置类
*主要核心:
* 扫描 创建单例Bean BeanDefinition:一个spring核心的对象,主要存放了spring初始化后的bean
* BeanPostPRocess: 主要实现aop,对bean初始化前和初始化后进行调用扩展
*/
LaoyangApplicationContext laoyangApplicationContext = new LaoyangApplicationContext(AppConfig.class);
//拿到我们自己的bean
UserService bean = (UserService) laoyangApplicationContext.getBean("userService");
//调用我们spring的自己的方法
bean.test();
}
}
2.模拟核心配置类(详细看代码)
package spring;
import laoyang.AppConfig;
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.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author:Kevin
* @create: 2023-09-08 20:51
* @Description: 老杨spring配置类
*/
public class LaoyangApplicationContext {
private Class AppConfig;
//bean扩展集合
private List beanPostProcessorList = new ArrayList<>();
//存放所有的bean信息
private Map beanDefinitionMap = new HashMap<>();
//存放所有的bean
private Map singletonObjects = new HashMap<>();
/**
* spring核心类配置: 1.获取到配置文件路径
* 2.扫描路径下的文件
* 3.根据注解生成bean存入容器
* @param appConfig
*/
public LaoyangApplicationContext(Class appConfig) {
this.AppConfig = appConfig;
//开始扫描
scan(appConfig);
}
/**
* 扫描:
* 1. 将配置文件目录的路径配置为绝对路径,遍历路径下的所有文件判断
* 2. beanDefinitionMap: 所有的bean信息
* 3. beanPostProcessorList:是否需要扩展的
* @param appConfig
*/
private void scan(Class appConfig) {
//判断配置类是否有ComponentScan属性
if (appConfig.isAnnotationPresent(ComponentScan.class)) {
//获取路径
ComponentScan annotation = appConfig.getAnnotation(ComponentScan.class);
String path = annotation.value();
path = path.replace(".", "/"); // com/laoyang/Service
//获取编译路径并封装成绝对路劲为了扫描我们自己的包下的bean
ClassLoader classLoader = LaoyangApplicationContext.class.getClassLoader();
URL resource = classLoader.getResource(path);
File file = new File(resource.getFile());
//判断是否目录
if (file.isDirectory()) {
for (File f : file.listFiles()) {
//获取绝对路径
String absolutePath = f.getAbsolutePath();
absolutePath = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class"));
absolutePath = absolutePath.replace("\\", ".");
try {
Class> clazz = classLoader.loadClass(absolutePath);
if (clazz.isAnnotationPresent(Component.class)) {
//判断这个类是否实现BeanPostProcessor,是否需要实现自定义扩展,aop的实现
if (BeanPostProcessor.class.isAssignableFrom(clazz)) {
BeanPostProcessor instance = (BeanPostProcessor) clazz.getConstructor().newInstance();
beanPostProcessorList.add(instance);
}
Component componentAnnotation = clazz.getAnnotation(Component.class);
String beanName = componentAnnotation.value();
if ("".equals(beanName)) {
//这里采用jdk的方法将给定字符串的首字母小写的方法。
beanName = Introspector.decapitalize(clazz.getSimpleName());
}
BeanDefinition beanDefinition = new BeanDefinition();
beanDefinition.setType(clazz);
//判断是否加入scope注解 ,是单例bean还是原型bean,默认单例bean
if (clazz.isAnnotationPresent(Scope.class)) {
Scope scopeAnnotation = clazz.getAnnotation(Scope.class);
String value = scopeAnnotation.value();
beanDefinition.setScope(value);
} else {
beanDefinition.setScope("singleton");
}
beanDefinitionMap.put(beanName, beanDefinition);
}
} catch (ClassNotFoundException | NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
/**
* 通过bean名称返回bean
* @param beanName
* @return
*/
public Object getBean(String beanName) {
if (!beanDefinitionMap.containsKey(beanName)) {
throw new NullPointerException();
}
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if (beanDefinition.getScope().equals("singleton")) {
Object singletonBean = singletonObjects.get(beanName);
if (singletonBean == null) {
singletonBean = createBean(beanName, beanDefinition);
singletonObjects.put(beanName, singletonBean);
}
return singletonBean;
} else {
// 原型
Object prototypeBean = createBean(beanName, beanDefinition);
return prototypeBean;
}
}
/**
* 创建bean的方法:
* 1. 依赖注入
* 2. 判断是否实现BeanNameAware:就是初始化bean名称
* 3. bean初始化前的操作
* 4,初始化bean
* 5. bean的初始化后的方法调用
* 6. 返回bean
* @param beanName
* @param beanDefinition
* @return
*/
private Object createBean(String beanName, BeanDefinition beanDefinition) {
Class clazz = beanDefinition.getType();
Object instance = null;
try {
instance = clazz.getConstructor().newInstance();
//依赖注入
for (Field field : clazz.getDeclaredFields()) {
if (field.isAnnotationPresent(Autowired.class)) {
//跳过访问权限直接修改
field.setAccessible(true);
field.set(instance, getBean(field.getName()));
}
}
//判断是否实现BeanNameAware:就是初始化bean名称
if (instance instanceof BeanNameAware) {
((BeanNameAware)instance).setBeanName(beanName);
}
//bean初始化前的操作,调用postProcessBeforeInitialization方法实现
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
instance = beanPostProcessor.postProcessBeforeInitialization(instance, beanName);
}
//初始化bean
if (instance instanceof InitializingBean) {
((InitializingBean)instance).afterPropertiesSet();
}
//bean的初始化后的方法调用
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
instance = beanPostProcessor.postProcessAfterInitialization(instance, beanName);
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return instance;
}
}
3. 核心配置类
package laoyang;
import spring.ComponentScan;
/**
* @author:Kevin
* @create: 2023-09-08 20:49
* @Description: 配置类
*/
@ComponentScan("com.laoyang.Service")
public class AppConfig {
}
4.