手写Spring框架
手写Spring框架
各位道友,我发现现在贼卷底层代码,看完源码发下几天后,额!!!我当时看了啥!
还是自己写个迷你的spring框架,这样印象更加深刻,上干货,代码仓库:https://gitee.com/smd_somin/SmdSpring.git
上面是我写的迷你版的spring框架,麻雀虽小,五脏俱全,主要包括下边的内容
- 容器启动
- BeanDefinition扫描
- Bean声明周期
- 单例与多例
- 依赖注入
- AOP
- aware回调
- 初始化
- BeanPostProcessor(增强器)
下面是手写框架的过程和思路,仅供大家参考!!!
相信大家总会遇到这样问题,聊聊你理解的spring?
这个基本是100个技术,99个会遇到这个问题?我谈一下我得理解,仅供参考,我认为spring可以用两行表示
//创建容器SmdApplicationContext context = new SmdApplicationContext(AppConfig.class);//获取对象UserInterface userService = (UserInterface) context.getBean("userService");
在这两行代码所牵连的内容其实就是spring的本质,对与bean的管理。
如果需要容器,那么我们需要有一个容器类,下面是手写spring容器的全部代码,这个也是逻辑的核心内容,下面会分享一下思路(建议对着源码看下):
上面的代码可以整体分为两个步骤,一个创建容器,另一个是从容器中获取bean。
首先说说创建容器的过程
创建容器 -> 扫描.class文件 -> 适配文件路径 -> 判断@Component注解 -> 符合注解进行反射获取对象 -> 记录bean的信息(类型,单例)-> 创建对象 -> 实例化对象 -> 依赖注入 -> aware增强类处理 -> 处理BeanPostProcessor的 postProcessorBeforeInitialazition方法 -> 初始化 -> BeanProcessor的beanPostProcessorAfterInitailzaiton方法 ->处理切面逻辑->bean创建成功
获取bean过程
主要区分单例还是多例,单例从单例池中取,多例新创建一个bean
SmdApplicationContext
package org.smd.spring;import java.beans.Introspector;
import java.io.File;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.smd.spring.annotation.Autowrite;
import org.smd.spring.annotation.Component;
import org.smd.spring.annotation.ScanComponent;
import org.smd.spring.annotation.Scope;
import org.smd.spring.aware.BeanNameAware;
import org.smd.spring.init.InitializingBean;/*** @author smd* @zhName 容器* @description: 容器*/
public class SmdApplicationContext {public Map<String, BeanDefinition> definitionMap = new HashMap();public Map<String, Object> singletonBeanMap = new HashMap();public List<BeanPostProcessor> beanPostProcessors=new ArrayList<BeanPostProcessor>();private Class configClass;public SmdApplicationContext(Class configClass) {this.configClass = configClass;//扫描文件夹下数据if (configClass.isAnnotationPresent(ScanComponent.class)) {ScanComponent scanComponent = (ScanComponent) configClass.getAnnotation(ScanComponent.class);//进行文件路径转化String path = scanComponent.vaule();System.out.println("-->scanComponent:" + path);path = path.replace(".", "/");System.out.println("-->scanComponent:" + path);//加载jar下.class文件ClassLoader classLoader = SmdApplicationContext.class.getClassLoader();URL resource = classLoader.getResource(path);File file = new File(resource.getFile());if (file.isDirectory()) {for (File f : file.listFiles()) {String filePath = f.getAbsolutePath();System.out.println("--> file path:" + filePath);if (filePath.endsWith(".class")) {String filesName = filePath.substring(filePath.indexOf("org"), filePath.indexOf(".class"));filesName = filesName.replace("\\", ".");System.out.println("-->file name" + filesName);try {Class<?> clazz = classLoader.loadClass(filesName);if (clazz.isAnnotationPresent(Component.class)) {if(BeanPostProcessor.class.isAssignableFrom(clazz)){BeanPostProcessor beanPostProcessor=(BeanPostProcessor) clazz.newInstance();beanPostProcessors.add(beanPostProcessor);}Component component = clazz.getAnnotation(Component.class);//获取bean nameString name = component.vaule();if (name.equals("")) {name = Introspector.decapitalize(clazz.getSimpleName());}//记录bean definitionBeanDefinition definition = new BeanDefinition();definition.setType(clazz);if (clazz.isAnnotationPresent(Scope.class)) {Scope scope = (Scope) clazz.getAnnotation(Scope.class);definition.setScope(scope.value());} else {definition.setScope("singleton");}//放入bean definition map中definitionMap.put(name, definition);}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();}}}}}//初始化beanfor (String name : definitionMap.keySet()) {BeanDefinition definition = definitionMap.get(name);Object bean = this.createBean(name, definition);singletonBeanMap.put(name, bean);}}private Object createBean(String name, BeanDefinition definition) {Class clazz = definition.getType();try {//实例化Object bean = clazz.getConstructor().newInstance();//依赖注入for (Field field : clazz.getDeclaredFields()) {if (field.isAnnotationPresent(Autowrite.class)) {field.setAccessible(true);field.set(bean, getBean(field.getName()));}}// aware加强类回调if(bean instanceof BeanNameAware){((BeanNameAware)bean).setBeanName(name);}// 初始化前调用bean post processorfor (BeanPostProcessor beanPostProcessor : beanPostProcessors) {bean= beanPostProcessor.postProcessorBeforeInitialization(name,bean);}// 初始化if(bean instanceof InitializingBean){((InitializingBean)bean).afterPropertiesSet();}// 初始化后调用bean post processorfor (BeanPostProcessor beanPostProcessor : beanPostProcessors) {bean= beanPostProcessor.postProcessorAftertInitialization(name,bean);}return bean;} catch (Exception e) {e.printStackTrace();}return null;}public Object getBean(String name) {//获取definition信息BeanDefinition definition = definitionMap.get(name);if (definition == null) {System.out.println("-->error:" + name);throw new NullPointerException();} else {//进行单例和多例区分if (definition.getScope().equals("singleton")) {Object bean = singletonBeanMap.get(name);if (bean == null) {return this.createBean(name, definition);} else {return bean;}} else {return this.createBean(name, definition);}}}
}
各位道友前路漫漫~ 努力向远方前进吧!!!
《真常之道,悟者自得,得悟道者,常清静矣。》