最近又重新温故下Spring源码深度解析。从网上 http://www.blogjava.net/zhyiwww/archive/2014/10/17/418809.html github上获取Spring的源码导入到idea里。过程也是百度参考很多次。最后成功的完成了.
之前也大致看过一遍Spring源码解析的pdf。但是每次面试或者给别人解释Spring源码时,总是感觉没办法深入,或者是解释的不够详尽。最后还是要翻看笔记,百度下才能获取到答案。
这次翻看源码。从网上借鉴黄宜华前辈的git代码 tiny-spring的项目先从基本的实现一个简单的Sping功能入手,来理解Spring的实现和代码编写风格。具体的gitHub:https://github.com/code4craft。同时参考了https://www.zybuluo.com/dugu9sword/note/382745 这篇文章 tiny-spring代码结构的分析,对这个简易的tiny-spring源码有了深入的理解。这次对自己做一次总结.

首先明确一下Spring框架的功能。这样我们从功能点来发现Spring是怎么实现的。我们能借鉴学到什么?
一、IOC的功能: 依赖注入,将自己编写的Bean交给Spring容器进行管理(包含Bean实例的newInstance,init初始化,销毁等)。
1. xml的配置
2. 使用注解@Controller @Service @Component 等等进行标记
在我们需要引用Bean实例的地方我们可以通过Spring容器上下文或者BeanFactory Bean工厂获取到对应bean的实例。或者通过注解@Autowired 和j2EE提供的注解@Resource注解获取单例的Bean实例
二、AOP的功能
AOP:面向切面编程-通俗一点,就是在一个切入点前执行一些自定义的业务逻辑,在切入点后执行一些自定义的业务逻辑。所以就相当于在切面前后进行业务逻辑处理的编写。从实现而言:我们可以想到的技术就是java的动态代理,对目标对象进行代理。使用代理对象执行业务逻辑。而代理对象包含对目标对象的引用。
而Spring的动态代理有两种方式:对于接口来说就是使用的JDK的动态代理来实现的(无法实现对类的动态代理),而对于类的代理使用CGLIB来实现。
三、SpringMVC的功能
Spring提供的MVC框架的实现
四、Spring的事务
五、Spring注解的实现

大家在开发中,对Spring的印象使用一般都是注解的注入。
即@Controller @Service @Component @Repository @RestController @RequestMapping @Autowired @PathVariable @RequestParam 等等
这些注解只是Spring对注解实现依赖注入的一部分。主要也是基于java提供的注解Annotation接口实现的自定义注解实现这些标记接口的功能
同时在日常开发,我们也会使用配置文件xml对bean进行配置管理。

IOC的实现

1.资源文件的封装。将xml、properties文件封装成Resource表示
2.使用 XmlBeanDefinitionReader 来解析xml文件(内部使用DOM方式解析xml文件。使用对应的xsd校验xml文件)
3.将xml的一个bean节点解析成一个BeanDefinition 。至于其他自定义的标签。根据标签获取对应命名空间将解析工作交给自定义的BeanDefinitionParser进行解析.(Spring中常用的自定义命名空间
AopNamespaceHandler、ContextNamespaceHandler、MvcNamespaceHandler
TaskNamespaceHandler、TxNamespaceHandler、UtilNamespaceHandler)
同时将bean中的每一个属性注入信息保存为PropertyValue 对象 。如果是对其他bean的引用
将properties的value值保存为BeanReference 对象 保存到PropertyValues数组里
最后保存到Map里 解析好的Bean的id和 BeanDefinition 键值对

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
——-至此完成了xml文件的解析工作和类上面标记的注解的扫描工作
4.初始化BeanFactory
根据Spring上下文AbstractApplicationContext refresh()方法。先注册所有的BeanPostProcessor.[这里AOP的反射就是通过实现BeanPostProcessor接口改变Bean的实例生成,返回Bean的代理]
并主动注册单例的Bean实例到BeanFactory中,这里重点是BeanFactory的getBean()创建Bean实例的方法

AOP

AOP是基于IOC实现的。
当使用注解 时。解析到该标签,会调用AopNamespaceHandler命名空间的里注册的解析器对标签进行解析。AspectJAutoProxyBeanDefinitionParser 会判断注册AnnotationAwareAspectJAutoProxyCreator.class到BeanDefinitionRegistry.最终会注册到DefaultListableBeanFactory中。

AnnotationAwareAspectJAutoProxyCreator 这个最终父类实际上是一个BeanPostProcessor接口的实现类。

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐