Spring学习笔记-加深对Spring的理解

写在前面

  在之前对Spring的学习和开发中,一直处于会用的状态,对Spring以及它的核心IOC、DI和AOP一直处于非常浅的认识。之前一直想找时间好好理解一下Spring,可是拖延症并没有让我这么做。不过,这次的课堂作业就是对Spring的理解,所以正好可以借这个机会查找相关资料来加深下对Spring的理解。


Spring简介

  Spring是一个开源框架,于2013年兴起的一个轻量级的Java开发框架,主要针对javaBean的生命周期进行管理的轻量级容器。Spring发展到现在,Spring所代表的已经不仅仅是一个框架,而是一系列Spring框架的集合,更像是一个Spring家族,其中包括:

  • Spring Framework —— Spring框架,包括了IoC, AOP, MVC以及Testing
  • Spring Data —— 一个用于简化数据库访问,并支持云服务的开源框架
  • Spring Security —— 基于Spring AOP和Servlet过滤器的安全框架 (我觉得这个框架太大了,我之后会学习Shiro)
  • Spring Boot —— 微服务框架,为基于Spring的开发提供更快的入门体验
  • …. —— 更多Spring家族的框架

7个核心模块

  Spring的7个核心模块大部分都是一些概念性的东西,所以我从网上摘了如下内容,原文网址见参考资料第一条。
  

  • 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
  • Spring上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
  • Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
  • Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
  • Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
  • Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
  • Spring MVC 框架: MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。

IOC/DI

  IOC:Inversion of Control 控制反转,不是一种技术,而是一种思想。一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。
  我是这么理解IOC的:在传统开发中,每个对象在要使用其它对象的时候,通常是使用new的形式创建对象,创建对象是开发者主动去创建的,也可以说创建对象的控制权是在开发者的手里,这样就会使对象间的耦合度变的很高,这显然不是一种好的开发方式。当然,在使用了Spring之后,创建对象的工作就交给Spring,将创建的对象存储到Spring容器中,所有的对象都交给Spring所管理。比如,当一个类(A)中调用另一个类(B),首先,这两个类都会被记录到Spring中,类A告诉Spring自己是什么,我需要类B。然后,Spring会创建这两个对象,在合适的时机将所创建的对象B交给对象A,并且将对象A交给其它需要对象A的对象。
  所以IOC,控制反转,就是说将创建对象的控制权由开发者自己转移到像Spring这样的第三方,由Spring来负责控制对象的生命周期和对象间的关系,是Spring的核心。开发者所创建的对象都由Spring所管理。。
  DI:Dependency Injection 依赖注入,动态的向某个对象提供它所需要的其他对象,依赖是通过外部注入的方式来实现的,很好的实现了解耦。

  IoC和DI由什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。


AOP

  当时学习Spring的时候,就被AOP搞的头晕,而且之后也一直没应用过AOP,到现在也没能弄明白什么是AOP,只记得它的中文翻译为:面向切片编程。以下摘自网络的专业解释:

  在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

  我是这么理解AOP的:在实际开发中,我们或多或少都会使用到同样的代码,最low的解决方案是通过复制粘贴来实现,这样的话,如果修改代码,则需要将所有粘贴的代码都进行修改,这显然是不被提倡的。稍微高级一点,是将那一段相同的代码封装成一个方法供其它方法进行调用,这样做能解决大部分场景的需求,但是难免会出现一些特殊情况,需要做到彻底的分离,这时就需要用到AOP了。下面举一个简单的例子:

  比如,我们按照需求实现一个注册功能,暂时只做了数据的基本校验,然后,需求更改,需要验证用户输入的用户名是否存在。这时,我们不应用AOP这种思想的话,肯定会修改之前写好的代码。可以,这种做法没问题,毕竟需求只是检查下用户名是否存在。可是,如果之后再次新增需求呢?如:发送验证短信信息、发送验证邮件、非法字符的过滤等等等等需求,这时如果依然采用之前的方法,就会使工作量变的很大。那么,使用了AOP思想的话,就不需要修改原有代码,我们只需要定义一个方法,不用在原有代码上调用该方法,系统就会自动执行这个方法。

  在Spring中,Spring的AOP代理由Spring的IoC容器负责生成、管理,其依赖关系也由IoC容器负责管理。因此,AOP代理可以直接使用容器中的其他Bean实例作为目标,这种关系可由IoC容器的依赖注入提供。——摘自第五个参考资料


小结

  这篇博客中,我只谈了我的理解,没有代码的具体实现。之后,会慢慢补充相关的代码实现。还有就是这些都是我主观的理解,如有错误,还请您指正。
  个人博客:https://www.howieli.cn 和个人CSDN博客: http://blog.csdn.net/howieli_1995


参考资料

Author: HowieLi
Link: https://www.howieli.cn/posts/spring-comprehend.html
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.