[适合初中级Java程序员修炼手册从0搭建整个Web项目](四)

简介: 前言文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206种一棵树最好的时间是十年前,其次是现在

six-finger-web


一个Web后端框架的轮子从处理Http请求【基于Netty的请求级Web服务器】 到mvc【接口封装转发)】,再到ioc【依赖注入】,aop【切面】,再到 rpc【远程过程调用】最后到orm【数据库操作】全部自己撸一个(简易)的轮子。

github


为啥要写这个轮子

其实是这样的,小六六自己平时呢?有时候喜欢看看人家的源码比如Spring,但是小六六的水平可能不怎么样,每次看都看得晕头转向,然后就感觉里面的细节太难了,然后我就只能观其总体的思想,然后我就想我如果可以根据各位前辈的一些思考,自己撸一个简单的轮子出来,那我后面去理解作者的思想是不是简单点呢?于是呢 six-finger-web就面世了,它其实就是我的一个学习过程,然后我把它开源出来,希望能帮助那些对于学习源码有困难的同学。还有就是可以锻炼一下自己的编码能力,因为平时我们总是crud用的Java api都是那些,久而久之,很多框架类的api我们根本就不熟练了,所以借此机会,锻炼一下。


特点

  • 内置由 Netty 编写 HTTP 服务器,无需额外依赖 Tomcat 之类的 web 服务(刚好小六六把Netty系列写完,顺便用下)
  • 代码简单易懂(小六六自己写不出框架大佬那种高类聚,低耦合的代码),能力稍微强一点看代码就能懂,弱点的也没关系,小六六有配套的从0搭建教程。
  • 支持MVC相关的注解确保和SpringMVC的用法类似
  • 支持Spring IOC 和Aop相关功能
  • 支持类似于Mybatis相关功能
  • 支持类似于Dubbo的rpc相关功能
  • 对于数据返回,只支持Json格式


絮叨

前面是已经写好的章节,下面我给大家来一一走一遍搭建流程

上次我们完成了基于Spring注解方式的ioc的注入,今天我们来看看简单的xml的实现,来学习一下xml的流程,只是最简单的了解一下xml流程,并没有多深入的去写里面的细节!


首先我们来看看包结构,来看看新增的东西

网络异常,图片无法展示
|



其实这节,就很简单了,就是增加几个类去解析xml文件,我也是用的人家的包,dom4j这个专门解析xml的。所以说其实也没有多少东西是我们写的,我们就是理解他的流程就好了,然后可以更好的去理解我们spring的源码,


来看看效果,和测试类


网络异常,图片无法展示
|


其实很简单,我就是在请求里面加入了这类,然后打印出来这个类,就好了

网络异常,图片无法展示
|


测试的后台打印

网络异常,图片无法展示
|


来看看改造的过程。


DefaultApplicationContext

DefaultApplicationContext->refresh()

网络异常,图片无法展示
|


其实就是这个地方,加载了xml的bean

XmlBeanDefinitionReader

package com.xiaoliuliu.six.finger.web.spring.ioc.beans.support;
import com.xiaoliuliu.six.finger.web.spring.ioc.beans.BeanDefinition;
import com.xiaoliuliu.six.finger.web.spring.ioc.exception.BeanDefinitionStoreException;
import com.xiaoliuliu.six.finger.web.spring.ioc.io.Resource;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
 * @author 小六六
 * @version 1.0
 * @date 2020/10/21 15:11
 * 解析xml文件 把它变成数据结构
 */
public class XmlBeanDefinitionReader {
    public static final String ID_ATTRIBUTE = "id";
    public static final String CLASS_ATTRIBUTE = "class";
    public List<BeanDefinition> loadBeanDefinitions(Resource resource) {
        InputStream is = null;
        List<BeanDefinition> result = new ArrayList<>();
        try {
            is = resource.getInputStream();
            SAXReader reader = new SAXReader();
            Document doc = reader.read(is);
            Element root = doc.getRootElement(); //<beans>
            Iterator<Element> iter = root.elementIterator();
            while (iter.hasNext()) {
                Element ele = (Element) iter.next();
                String id = ele.attributeValue(ID_ATTRIBUTE);
                String beanClassName = ele.attributeValue(CLASS_ATTRIBUTE);
                BeanDefinition bd = new BeanDefinition(beanClassName, id);
                result.add(bd);
            }
            return result;
        } catch (Exception e) {
            throw new BeanDefinitionStoreException("IOException parsing XML document from " + resource.getDescription(), e);
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
复制代码


Resource

package com.xiaoliuliu.six.finger.web.spring.ioc.io;
import java.io.IOException;
import java.io.InputStream;
/**
 * @author 小六六
 * @version 1.0
 * @date 2020/10/21 15:18
 */
public interface Resource {
    public InputStream getInputStream() throws IOException;
    public String getDescription();
}
复制代码


ClassPathResource

package com.xiaoliuliu.six.finger.web.spring.ioc.io;
import com.xiaoliuliu.six.finger.web.spring.ioc.util.ClassUtils;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
 * @author 小六六
 * @version 1.0
 * @date 2020/10/21 15:32
 */
public class ClassPathResource implements Resource {
    private String path;
    private ClassLoader classLoader;
    public ClassPathResource(String path) {
        this(path, (ClassLoader) null);
    }
    public ClassPathResource(String path, ClassLoader classLoader) {
        this.path = path;
        this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());
    }
    @Override
    public InputStream getInputStream() throws IOException {
        InputStream is = this.classLoader.getResourceAsStream(this.path);
        if (is == null) {
            throw new FileNotFoundException(path + " cannot be opened");
        }
        return is;
    }
    @Override
    public String getDescription(){
        return this.path;
    }
}
复制代码


结尾


好了,总的来说,这篇文章其实也没什么,其实就是把xml变成beandifinition 这个是核心,不管是基于注解的,还是基于xml最终的形态是相同的。下章我们就来看看aop吧!fighting吧!

相关文章
|
1月前
|
IDE Java 应用服务中间件
Java Web开发入门指南:从基础到实践
Java Web开发入门指南:从基础到实践
|
SQL Java 关系型数据库
java程序员怎么创建自己的网站:第五章:图解阿里云服务器部署SpringBoot项目
java程序员怎么创建自己的网站:第五章:图解阿里云服务器部署SpringBoot项目
146 0
java程序员怎么创建自己的网站:第五章:图解阿里云服务器部署SpringBoot项目
|
Dubbo 前端开发 Java
[适合初中级Java程序员修炼手册从0搭建整个Web项目](九)
前言 “ 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206 种一棵树最好的时间是十年前,其次是现在
110 0
|
前端开发 Dubbo Java
[适合初中级Java程序员修炼手册从0搭建整个Web项目](一)
前言 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206 种一棵树最好的时间是十年前,其次是现在
93 0
|
JSON 前端开发 Java
[适合初中级Java程序员修炼手册从0搭建整个Web项目](二)
前言 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206 种一棵树最好的时间是十年前,其次是现在
107 0
|
SQL XML 前端开发
[适合初中级Java程序员修炼手册从0搭建整个Web项目](十)
前言 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206 种一棵树最好的时间是十年前,其次是现在
111 0
|
缓存 Dubbo 前端开发
[适合初中级Java程序员修炼手册从0搭建整个Web项目](七)
前言 “ 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206 种一棵树最好的时间是十年前,其次是现在
100 0
|
负载均衡 前端开发 Dubbo
[适合初中级Java程序员修炼手册从0搭建整个Web项目](八)
前言 文本已收录至我的GitHub仓库,欢迎Star:github.com/bin39232820… 种一棵树最好的时间是十年前,其次是现在
110 0
|
Dubbo 前端开发 Java
[适合初中级Java程序员修炼手册从0搭建整个Web项目](六)
前言 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206 种一棵树最好的时间是十年前,其次是现在
117 0
|
Java 程序员 Spring
[适合初中级Java程序员修炼手册从0搭建整个Web项目](五)(下)
前言 “ 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206 种一棵树最好的时间是十年前,其次是现在
77 0