# Spring-Datazn **Repository Path**: pku_roco/spring-datazn ## Basic Information - **Project Name**: Spring-Datazn - **Description**: 手写Spring框架 - **Primary Language**: Unknown - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-05-23 - **Last Updated**: 2022-06-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 2022.5.22 添加了解析包路径下的class类,并创建实例 主要的数据结构: - classLoader 类加载器,一共有三种 - Bootstrap ---> jre/lib - Ext ---> jre/ext/lib - App ---> classpath - singletons - 单例池,存放所有的单例bean - beanDefinition - bean定义类,靠这个类进行bean的实例化 - BeanDefinitionMap - 维护当前Spring容器中有哪些bean对象 已实现的注解: 1. component 2. componentScan 3. scope 2022.5.23 添加了autowired功能 我的逻辑是,创建bean对象和对bean对象注入需要分离。 扫描包以后进行bean单例的创建 当需要getBean时,若 1. 是单例bean,进行单例bean注入,即找到bean以后,进行注入 2. 是原型bean,需要先创建,创建以后,实例传入注入方法,然后注入 BeanNameAware 对实现了BeanNameAware接口的Bean对象,获取到beanName 在创建Bean对象时进行判断,如果实现了BeanNameAware,就把beanName赋给它 回调: 回调可以让用户在实例化bean之后,获取之前最后调整一下Bean 想要实现这个功能的,只要实现InitializingBean方法,在初始化的时候,特地查看了bean是否实现了该接口,如果实现了,就把这个方法传进来。 大功能: BeanPostProcessor 在扫描的时候,将BeanPostProcessor的beanName放到List中 在getBean的时候,如果遇到了是BeanPostProcessor的情况,getBean出来,然后实例化并运行它的方法 如果不是BeanPostProcessor,就照常做 2022.5.24 1. 让Spring管理Config对象,设为Singleton 2. AOP机制:在AfterInitializing中,拦截一下config bean并给它Load出来 3. NIOServer 1. 通过Bean获取到配置 2. NIO服务器三大组件: - ByteBuffer - SocketChannel - Selector 思路是先将serverSocketChannel注册到Selector上,注册为ACCEPT事件 然后监听端口,当轮询器发生事件时,交给Handler类 3. Handler 将发生的事件对SelectorKey传进来,判断: - 如果是Accept事件,就接收SocketChannel client注册到Selector上,并注册为Read事件 - 如果是Read事件,就将Read的信息绑定到key的attach上,然后将事件注册成Write事件 - 如果是Write事件,将attachment拿出来,然后处理,将事件注册成Read事件 2022.5.25 NIOServer 1. http请求头格式 method='GET', uri='/oa/inde.htm', protocol='HTTP/1.1' 处理静态页面请求:将uri定位到文件,通过输入流读到bytebuffer然后write 要注意添加响应头: HTTP/1.1 200 OK Content-Length: 4096 Content-Type: text/html; charset=UTF-8 难点: 1. nioserver发送的消息,普通socket的getInputStream收不到。 2. 因为用两个Selector分开注册事件和读写事件,因此要将注册完毕的Channel登记到读写那边的selector,而这个时候selector可能正在select阻塞,但是又没有读写事件导致死锁。 解决方案: 先将登记到读写selector的任务放到任务队列里,然后唤醒Selector,让他执行下去,执行好了读写就处理任务队列的任务。 2022.5.26 能够响应所有静态资源,主要是通过socketchannel的write方法进行发送 请求头和请求体分开发送 通过后缀名获得对应的content-type 主要是处理get请求 2022.5.27 实现注解RestController, 该注解的对象自动为一个JavaBean,当有请求路径与RestController的前缀对上时,就将对应的url发送到下面的mapper 方案: 维护一个List,里面存放了所有Controller,每当对应上的Controller被发现,就放进去。 在GetHandler内进行处理 获取参数列表,将参数按名给到involve # 改进点 1. com.datazn.nioserver.core.handler.Handler下面的suffixMap可以改进。 2. 注解可以很大改进 3. 用=粗暴地分割可能会有问题 2022.5.28 打包成Jar包后的一系列问题: 1. jar包内的resources找不到,需要通过反射的getResourceAsStream获取到文件流,再通过建立临时文件获得。 2. jar包内找不到Class,需要通过JarFile的方法进行获取 bytebuffer和buffer的问题: 1. byte[]需要维护新的,不然会导致文件部分内容重复。 2. byte如果是固定长度,会导致结尾有null填充。 解决方案:将byte[]长度固定为1 2022.5.29 新增jdbc连接池,利用blockingqueue的特性 2022.5.31 新增BaseMapper类,来处理JDBC