您的位置:首页 > 编程语言 > Java开发

不想去读spring庞大源码,欲了解其内部原理来读此文

2017-11-21 20:13 381 查看
本文假设读者已经知道如何使用spring了,或者至少曾经简单使用过一次,
比如知道如何写注释,如何写xml文件!


1: 设计工厂模式

实现spring提供类的注册和获取

factory(map<String, BeanDef>, getBean)


2: 因为创建类的过程可以让用户自己实现,所以可以在1的基础上抽象出一个抽象工厂类

abstract class AbstractBeanFactory implements BeanFactory {
//创建类,抽象方法
// 获取类,实现
//注册类。 实现
}


因为spring提供了一个xml的文件配置,生成实例,而且告诉我们如何实现有参构造函数的生成实例(这个后面说)

那么,我就在AbstractBeanFactory 的上层,继承一个子类:。实现创建类的方法!(这就是autowired啦!)

一般的实例生成,那我就用class.getInstance()即可!

3: 在2 中遗留了一个问题,就是如何生成有参实例的生成,也就是属性的注入autowired!

定义PropertyVal和PropertyName 作为参数键值对,那么所有xml中的参数都是这两个类,

在2的基础上,不过是,反射一下即可!

// @hxx
Field declaredField = bean.getClass().
getDeclaredField(propertyValue.getName());
declaredField.setAccessible(true);
declaredField.set(bean, propertyValue.getValue());


所以到第3,就讲完了spring的【生成类,注册类,获取类】三个功能~

4: 这一步,我如果说写如何读取xml文件,并且解析中间的格式,大家一定不会反对吧!

java.io的代码就不贴出来了!

看spring的源码lib中,是借用w3c.dom!

假设到这一步,我将xml文件中的所有property(name,value)都放到了1中的map了!

5: spring ioc ,终于看到核心点了

有谁在看完前面1-4,觉得有不妥的地方吗? 往上滑,你会发现3中有一段代码标注着@hxx,这是我代码的@author,但我只是想重点标注一下这段代码!

在创建类时候,如果是简单的基本类型的属性注入,那么很好说,但是大多数的属性都会是一个对象!

如果不知道缺少什么,那么截取一下官方文档中的一句话:

public interface BeanReference
extends BeanMetadataElement
Interface that exposes a reference to a bean name in an abstract fashion. This interface does not necessarily imply a reference to an actual bean instance; it just expresses a logical reference to the name of a bean.


简单的说,就是用id来标示一个bean.

那我们实现这个BeanReference(BR): 一个name ,一个object(对应着map中的某个类型)

Field declaredField = bean.getClass().getDeclaredField(propertyValue.getName());
declaredField.setAccessible(true);
Object value = propertyValue.getValue();
if (value instanceof BR) {
BRbeanReference = (BR) value;
value = getBean(beanReference.getName());
}
declaredField.set(bean, value);


ioc 的控制和反转都大概说完了!

6: 顺其自然,一鼓作气,讲spring aop。

之前看过一个公众号,讲动态代理,讲的非常好,用java帝国国王和大臣的讨论来介绍设计初衷和思路!公众号叫“码农”,大家可以关注!

这里使用java动态代理

使用动态代理,需要具备的是:

首先你要切入的service必须设计一个接口。

设计思路

1:准备 切入的service对象(比如说LogService)

并使用接口,将此对象传入后,生成一个target

2: 准备切面服务类,比如说是一个MonitorSvc

target把这个切面服务类注入

TimerInterceptor timerInterceptor = new TimerInterceptor();
advisedSupport.setMethodInterceptor(timerInterceptor);


3: 创建动态代理

思考,人家的代码是如何写的!

我们在写一个实现一个功能的时候,取好一个名字,就开搞了,一个类里刷刷刷就是搞,可能一个方法有数百行。好一点的知道多拆几个方法!但是spring源码中,基本上所有的功能都先设计一个抽象类或者接口!所以,我写这篇文章真正看代码的时间非常少,因为很多逻辑只看接口即明白了,封装设计不仅让自己思路清晰,更让为你的继承人铺了一条康庄大道!


大家可以关注我的个人公主号,蝙蝠侠Lee,一期探讨或者索要文中demo

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息