聊聊spring

spring对于java开发者来说,是最熟悉不过的框架了,我们日常开发中每天都在使用它。它有着各种各样的好处,简单易用,得心应手... ...

我们一说到spring就会讲到ioc 、aop、依赖注入,注解等专业名词,不少刚接触java的人,都是一头雾水,很难直观的去理解这些是个什么玩意,但使用的多了 就爱上了它给我们带来的便利。

探索spring

当我们熟练的使用它之后就会好奇,ioc怎么实现的呢?为什么我只要在类的变量中加入@AutoWrited 就能使用这个变量?带着疑惑我们就会开始翻源码,找答案。经过一番努力,最终我们定位到了spring-context.jar包,找到了

AbstractApplicationContext对象的refresh方法,这里面的实现和步骤,就是整个spring功能的核心,里面的实现另我们叹为观止,但也相当之复杂,用到了很大设计模式,难以窥见全貌,很多地方的设计我们不知道为啥需要这么实现。但我们还是知道了ioc容器实际上是用的Hashmap,
依赖注入使用的是反射,aop实际上是动态代理完成的。还有很大一部分代码看的有点晕,就是加强健壮性保证生命周期和各种特性的。不管怎么说,那都是别人的东西,我们只会用,源码我们看了很多,但很少自己来实现出来。

spring实现分析

不管怎么说,别人的实现是别人的,自己写出来的东西是属于我们自己的。既然下决心要自己也能实现了,那我们就需要分析分析了。

spring怎么做到代码侵入量少且各层级分明的呢?

spring采用约定大于配置,按照固定模式,层级分为Controller 、Service、Component、Bean、Configuration来标识类型

spring是怎么管理依赖关系的?

是通过注解或xml

spring是怎么发现哪些类需要管理的?

是注解标记+包路径扫描

spring是如何实现依赖注入的?

通过AutoWrited注解标记加反射实例化对象

spring是如何管理Bean的?

使用HashMap容器、Set容器实现单例Bean

spring怎么实现aop切面的呢?

使用动态代理的方式,并提供了cglib和jdk默认实现两种方式

spring是在何时加载到内存中的呢?

springMvc是通过web.xml配置入口触发,springboot是通过springApplication初始化触发

本次实现spring核心功能会涉及到哪些点?

1.注解的定义与使用

2.容器的初始化

3.配置文件的读取与使用

4.sevlet的使用

5.注解的定义与使用

6.反射的运用

7.url路由与方法映射

8.参数解析与绑定

9.正则与转义

正式开始

首先创建一个maven项目,代码结构如下:

添加jar包依赖:

里面有2个jar包加一个插件

javax.servlet-api.jar 用来启动核心代码和处理请求
fastjson.jar          用来做json参数绑定

jetty-maven-plugin    使用jetty作为web容器启动 

完整maven代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.honstat</groupId>
<artifactId>test-spring</artifactId>
<version>1.0-SNAPSHOT</version> <dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency> <dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.56</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.5.v20170502</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<webApp>
<contextPath>/</contextPath>
</webApp>
<httpConnector>
<port>8080</port>
</httpConnector>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

创建前端控制器类

前端控制器专门处理servlet请求,匹配到对应的方法执行后返回,前端控制器是什么可以参考我的另一篇博客《SpringMvc请求处理流程与源码探秘》

这里我们创建一个叫CJDispatcherServlet的类,它继承HttpServlet类,并且重写HttpServlet的init(),doGet(),doPost() 这3个方法,图中的HomeService和StudentService可以先忽略不写

配置web.xml

需要配置<servlet> 和<servlet-mapping> 2个标签

<servlet>中需要

1.指定servlet名称

2.指定处理请求的前端控制器类

3.设置初始化配置文件路径

完整web.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee"

         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

         version="2.5">
<servlet>
<servlet-name>cjservletMVC</servlet-name>
<servlet-class>com.honstat.spring.service.CJDispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>spring/application.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>cjservletMVC</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>

添加注解

我们知道,spring里面是通过给类加注解来识别各种使用场景的,那我们就来实现几个必用的

作用在类上的:

JCController

JCService

JCComponent

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface JCController {
String value() default "";
}

全部采用这种类型

作用在方法上和类上的:

JCRequestMapping

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface JCRequestMapping {
String value() default "";
}

作用在字段上的:

JCAutoWrited

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface JCAutoWrited {
String value() default "";
}

到此我们已经初步的创建完了需要准备的类,准备工作告一段落。


由于篇幅有限,下一篇开始实现核心功能了!

完整代码地址

自己实现spring核心功能 一的更多相关文章

  1. Spring 核心功能演示

    Spring 核心功能演示 Spring Framework 简称 Spring,是 Java 开发中最常用的框架,地位仅次于 Java API,就连近几年比较流行的微服务框架 SpringBoot, ...

  2. 自己实现spring核心功能 三

    前言 前两篇已经基本实现了spring的核心功能,下面讲到的参数绑定是属于springMvc的范畴了.本篇主要将请求到servlet后怎么去做映射和处理.首先来看一看dispatherServlet的 ...

  3. 自己实现spring核心功能 二

    前言 上一篇我们讲了spring的一些特点并且分析了需要实现哪些功能,已经把准备工作都做完了,这一篇我们开始实现具体功能. 容器加载过程 我们知道,在spring中refesh()方法做了很多初始化的 ...

  4. spring 核心

    1 Spring 1.1 专业术语了解 1.1.1 组件/框架设计 侵入式设计 引入了框架,对现有的类的结构有影响:即需要实现或继承某些特定类. 例如:     Struts框架 非侵入式设计 引入了 ...

  5. 读源码之Spring 核心内容

    为什么有这篇文档 工作两三年之后,总感觉什么东西都懂,但是什么东西又都不会.所以日常学习是很有必要的,俗话说学而不思则罔 ,思而不学则殆.所以我们要学思结合,学习的方法有很多,但是思考的深度或者说有没 ...

  6. Spring框架的IOC核心功能快速入门

    2. 步骤一:下载Spring框架的开发包 * 官网:http://spring.io/ * 下载地址:http://repo.springsource.org/libs-release-local/ ...

  7. Spring 框架的核心功能之AOP技术

    1. AOP 的概述 AOP, Aspect Oriented Programming, 面向切面编程; 通过预编译方式和运行期动态代理实现程序功能的统一维护的技术; AOP 采取横向抽取机制,取代了 ...

  8. Spring框架的核心功能之AOP技术

     技术分析之Spring框架的核心功能之AOP技术 AOP的概述        1. 什么是AOP的技术?        * 在软件业,AOP为Aspect Oriented Programming的 ...

  9. 第一章 spring核心概念

    一.Spring作用:管理项目中各种业务Bean(service类.Dao类.Action类),实例化类,属性赋值 二.Spring IOC(Inversion of Control )控制反转,也被 ...

随机推荐

  1. Redis 使用C#程序操作Redis

    一.安装操作所需Nuget包 二.写入 redis只是按Key值设置过期时间,不是对value内部的某些值设过期 2.1 string类型 /// <summary> /// 向Redis ...

  2. 20190716 NOIP模拟测试4 考试反思

    总分 127分 满分300 第一题 礼物 10分 一道期望题,看起来挺简单,但对于概率与期望这一块我还不怎么会,花了一个小时调他,最后只QJ了一下10%的测试点 第二题 通讯 90分 显然的缩点求解, ...

  3. QQ Music 音乐插件DFX unable to open skin configration 的解决方法

    设置 C:\Program Files (x86)\Tencent\QQMusic\Plugins\Dfx\dfx_skin.txt  它的权限 允许程序读取执行

  4. NOIP2018提高/普及成绩

    明天就要出了,不忍看到自己爆零,现在很慌. 大家都考的如何呢?欢迎留言自己的分数或预估分数.

  5. WePY的脱胎换骨

    对于前端来说,尤其是开发小程序的前端来说,WePY框架一定不陌生,他是一种小程序开发框架.而且是属于类Vue风格,掌握Vue再来学习WePY学习成本极低. 今天为啥要写这篇文章呢,因为在复习WePY时 ...

  6. Baozi Leetcode solution 1036: Escape a Large Maze

    Problem Statement In a 1 million by 1 million grid, the coordinates of each grid square are (x, y) w ...

  7. [剑指offer] 46. 孩子们的游戏(圆圈中最后剩下的数)

    题目描述 随机指定一个数m,让编号为0的小朋友开始报数.每次喊到m-1的那个小朋友要出列,并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去....直到剩下最后一个小朋友 ...

  8. 【带着canvas去流浪(13)】用Three.js制作简易的MARVEL片头动画(下)

    目录 一. 模型的制作 1.1 生成字体模型 1.2 多表面贴图 二. 镜头及动画 三. 大作业总结 示例代码托管在:http://www.github.com/dashnowords/blogs 博 ...

  9. 前端手势控制图片插件书写四(图片上传及Ios图片方向问题)

    1.在图片上传中,使用的input的type为File的属性.使用filereader的Api let that = this; var file = document.getElementById( ...

  10. 手动创建MySQL服务

    1.复制一份MySQL服务文件,放入一个路径 2.清理data文件夹下文件,仅保留mysql等 3.修改my.ini,port,...dir等配置 4.管理员运行cmd,cd>bin:mysql ...