Spring 核心

Spring 核心

这篇文章,我们换个思路来学习,来践行一下以始为终,以面试题为引来重温一下Spring,毕竟孔子曾说,"温故而知新,可以为师矣。" ,可以通过这个链接看看有哪些常见的面试题

Spring 面试题 - 面试鸭 - 程序员求职面试刷题神器

面试题虽然很多,但是如果我们抓住Spring的本质,那么一切都显得有迹可循。如果你能静下心来通读Spring的官方文档,那么你就会觉得一切都是那么自然。所有的答案都在文档和源码中。所以这部分内容,我替代不了你,你需要自己通读一遍官方文档。这篇文章主要是对核心的内容做一个总结仅此而已。

Spring IOC

Spring中最基础的组件莫过于IOC容器,在聊IOC容器之前,我们先来看看IOC是什么?IOC是Inversion of Control 翻译为中文为控制反转,名字不重要,重要的是理解IOC的思想。在面向对象的软件设计中,一切皆对象,对象与对象之间存在依赖关系,一个功能往往需要多个对象互相配合才能实现。举个例子,用户下单这个功能,就需要订单服务与商品服务相互配合,在用户下订单之后,订单服务就会增加一个有关这个用户的订单,商品服务也会将对应的商品库存进行扣减,换句话说完成这个功能,需要订单服务对象,商品服务对象。而对象往往需要创建之后,甚至进行一些初始化操作才可用。如果将这类对象创建以及初始化的代码和业务代码耦合 在一起,随着项目的扩展,整个工程就将变得难以维护。而IOC就是来解决这个问题的,即将对象创建以及初始化的代码与业务代码隔离开来。让开发人员可以更加关注业务代码,减轻开发人员的负担。而Spring IOC容器只不过是这种思想的一种实现。

那么问题来了,Spring IOC容器是如何将对象的创建与业务代码隔离的呢?这就不得不提出Spring中的另一个概念了,Spring Bean,Spring Bean就是被IOC容器管理的对象。而Bean的创建是基于一系列的配置,这些配置可能来自于XML配置文件,也可能来自Java代码。目前常用的配置Bean的方式是利用Java代码。具体而言就是我们熟知的这些注解 @Component @Service @Controller 以及 @Bean

举个例子方便大家理解,比如下面这段代码

java 复制代码
@Service
public class StoreServiceImpl implements StoreService {
    @Override
    public Object findByName(String name) {
        return "Mock Account";
    }
}

当Spring启动的时候,会扫描指定包下的全部class文件,如果扫描到有关Bean配置的注解,比如这里的@Service 就会创建一个BeanDefinition对象,这个对象对应的就是Bean的元信息,换句话说就是Bean的配置信息,然后Spring就可以根据这些配置信息创建出一个Bean对象来,也就是这里的StoreServiceImpl 对象。至于BeanDefinition的具体配置信息可以参考这个类GenericBeanDefinition

对象是创建完毕了,那么这些对象应该放在哪里呢?答案是在一个Map中,这也就是为什么IOC容器中有容器这两个字了。

这个Map就是存在Spring创建Bean对象的地方,这样子的容器有三个,这里先不讨论。

既然IOC容器负责管理对象,那么对象之间的依赖关系也需要IOC容器来解决,这就是我们常说的依赖注入即DI。而依赖注入最常见的问题就是依赖循环。场景的依赖循环场景有这样三个

  1. 对象A依赖对象B,对象B依赖对象A
  2. 对象A依赖对象B,对象B依赖对象C 对象C依赖对象A
  3. 对象A依赖对象A

Spring的IOC容器其实解决了大部分的依赖循环的问题,具体的解决办法就是利用上面提到的那三个容器。也被叫做Spring的三级缓存。但是需要注意的是,出现依赖循环,这个问题是设计上的问题,所以如果出现依赖循环,我们应该想想如果改造设计,而不是指望Spring来帮我们解决。

要说在Spring中可以和IOC容器这个特点相提并论的就只有Spring AOP了。

Spring AOP

AOP是一种编程范式,和面向对象编程一样,它的名字叫做面向切面编程,其本质其实是代理模式的运用。比如,在API的管理中,有些API只有级别比较高的用户才能使用,那么我们不得不进行权限校验,这类代码在每个API中都会使用,如果让这些代码与业务代码写在一起,就会过于耦合。而AOP就是将这类通用逻辑的代码与变化较多的业务代码隔离开来。大部分的AOP实现都是使用代理模式实现的。Spring AOP也不例外,使用的是基于类的动态代理,而不是Java标准库自带的基于接口的动态代理。更加详细的内容可以参考官方文档 https://docs.spring.io/spring-framework/reference/core/aop.html ,正如我之前提到的那样,如果你有时间,你一定要去通读Spring的官方文档,你一定会收获颇多。

Spring提供了很多好用的特点,可以简化我们的开发,比如,声明式事务,异步任务,条件注解,事件驱动模式等等。但是这些特点都是基于IOC容器以及AOP来实现的。所以彻底理解Spring IOC和Spring AOP的内容很重要。

如果你时间不充裕,我也推荐你读一读Spring官方文档中IOC以及AOP相关的内容

The IoC Container :: Spring Framework

Aspect Oriented Programming with Spring :: Spring Framework

相关推荐
神仙别闹14 分钟前
基于java的改良版超级玛丽小游戏
java
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭38 分钟前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫1 小时前
泛型(2)
java
超爱吃士力架1 小时前
邀请逻辑
java·linux·后端
南宫生1 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石1 小时前
12/21java基础
java
李小白661 小时前
Spring MVC(上)
java·spring·mvc
GoodStudyAndDayDayUp2 小时前
IDEA能够从mapper跳转到xml的插件
xml·java·intellij-idea
装不满的克莱因瓶2 小时前
【Redis经典面试题六】Redis的持久化机制是怎样的?
java·数据库·redis·持久化·aof·rdb
n北斗2 小时前
常用类晨考day15
java