一文看懂 Spring IoC 核心特性

简介: 恰逢最近在部门内部做分享,借着这次机会对 Spring IoC 部分又进行了系统的整理,由于大家专业方向和水平不完全一致,因此更多的是让大家了解 Spring 这门技术,分享的内容也站在了更高的角度,希望达到鸟瞰全貌的目的。

前言


恰逢最近在部门内部做分享,借着这次机会对 Spring IoC 部分又进行了系统的整理,由于大家专业方向和水平不完全一致,因此更多的是让大家了解 Spring 这门技术,分享的内容也站在了更高的角度,希望达到鸟瞰全貌的目的。


PPT 多用于演讲,重点在于让观众短时间内理解演讲者的观点,因此表现形式就比较重要,有句话说的是 字不如表,表不如图,因此 PPT 更多的是以大量的图片,简短的文字让观众一眼看明白。


不过博客与 PPT 有所不同,主要靠观众阅读,因此可以用更多的文字与代码表达想法。这篇内容相比前面一些文章更加大白话,更符合大众口味,旨在让大家理解 Spring IoC 的特性。


重学 Spring,从 IoC 谈起


学习 Spring,一定是先从 Spring 的 IoC 容器谈起,这是为什么呢?


事实上这和 Spring 的诞生背景有一定的关系。Java 从 1995 年诞生后由于 ”write once, run any where“ 的特性,各应用开发商均在 Java 标准版的基础上开发企业级的 API。为了简化企业级应用的开发,Sun 公司联合了 IBM、Oracle 等多家公司共同制定了企业级应用系统开发规范,即 J2EE。EJB 就是 J2EE 规范的一部分,作为业务逻辑层的中间件技术,定义了 EJB 组件如何与 EJB 容器进行交互。


73.png


不过呢,EJB 实在太难用了,不仅 API 复杂,而且应用与这套 API 耦合程度太高了,必须实现特性的接口才可以,更要命的是它的 RPC 调用会应用性能下降很多。


这个时候,有一个叫 Rod Johnson 的哥们有了新想法,他写了一本书叫 《Expert One-on-One J2EE Design and Development》,提出可以用普通的 Java 类和依赖注入解决 J2EE 的缺陷,这本书中的开源框架被称为 interface 21,这就是 Spring 的前身。


其中依赖注入就是 IoC 的实现方式之一,Spring 最初也是按照 IoC 容器的方式来进行设计,因此只要学习 Spring 就会先从 IoC 的相关概念学起。


Spring 核心特性


不过呢,Spring 可不仅仅是一个 IoC 容器,它在 IoC 容器的基础上扩展了很多能强有力的功能,了解这些功能特性才能知道 Spring 能做什么。


Spring 的核心特性有 9 个,下面分条介绍。


74.png


控制反转(IoC)


控制反转的目的是借助容器实现具有依赖关系的对象之间的解耦。

假定有如下的两个 Service。


public interface IServiceA {
    String format(Object obj);
}
public class ServiceAImpl implements IServiceA {
    @Override
    public String format(Object obj) {
        return String.valueOf(obj);
    }
}
public interface IServiceB {
    String format(Object obj);
}
public class ServiceBImpl implements IServiceB {
    private IServiceA serviceA;
    public ServiceBImpl(IServiceA serviceA) {
        this.serviceA = serviceA;
    }
    @Override
    public String format(Object obj) {
        return this.serviceA.format(obj);
    }
}


IServiceA 与 IServiceB 都定义了格式化对象的方法,其中 IServiceB 的实现依赖了 IServiceA,将 ServiceAImpl 和 ServiceBImpl 两个类配置到 Spring 容器中作为 bean,然后 ServiceBImpl 就可以直接使用 IServiceA 的实现,而不用关系依赖从哪来。


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="serviceA" class="com.zzuhkp.demo.bean.ServiceAImpl"/>
    <bean id="serviceB" class="com.zzuhkp.demo.bean.ServiceBImpl">
        <constructor-arg name="serviceA" index="0" ref="serviceA"/>
    </bean>
</beans>


public class Application {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:context.xml");
        IServiceB serviceB = context.getBean(IServiceB.class);
        System.out.println(serviceB.format("hello spring ioc"));
        context.close();
    }
}

如果 ServiceBImpl 依赖的 ServiceAImpl 不满足需求,直接修改 bean 配置,将其替换为其他 IServiceA 的实现即可,从而实现了依赖解耦。


面向切面编程(AOP)


面向切面编程(AOP)主要用来补充面向对象编程(OOP),而不是用来替换 OOP,OOP 模块化的单位是类 Class,而 AOP 模块化的单位则是切面 Ascpet。AOP 将跨域多个 Class 的关注点模块化到 Aspect,如日志、鉴权等等。


Aspect 可以在方法执行前后执行一些动作。由于 Java 是静态强类型语言,因此无法修改原有类型,通常的做法是动态生成原有类型的代理类型,在执行原有类型的方法时,添加额外的逻辑。


JDK 自带的动态代理基于接口,如果原有类型没有实现接口,则只能代理类型只能继承原有类型,Spring 选用的是 CGLIB 动态创建代理类。Spring 在 bean 的生命周期中预留了很多回调,在生命周期阶段创建 bean 的代理即可。


Spring AOP 的使用方式可以参见《Spring AOP 的三种使用方式》,这里不再赘述。


国际化(i18n)


国际化也是 Java Web 开发常用的一个功能,常用于 Web 站点渲染、校验使用的一些文案,不同国家的人展示不同的语言,这样对用户会更为友好。


JDK 自身已经对国际化进行了支持,不过 JDK 自身的国际化只能根据国家信息,从某个资源文件中根据某个 key 获取对应的值,这个值本身可能还包含一些占位符需要进行格式化。


Spring 的国际化将 JDK 国际化与消息格式化进行了整合,提供了一个 MessageSource 接口,使用上更为简便,直接将其作为依赖注入即可。


更多 Spring 国际化的内容,可以参见《Spring 国际化支持之 MessageSource》,不再赘述。


数据绑定(data binding)


数据绑定是指将元数据设置到对象的属性中,用户直接使用数据绑定的场景并不多,在 Spring 内部有两种地方使用数据绑定,一处是 xml 配置中的 bean 属性设置到对象中,另一处是将 http 请求数据设置到对象中。


如果你想了解数据绑定的更多内容,可以参见《聊聊 Spring 核心特性中的数据绑定 (DataBinder)》。


类型转换(type convert)


类型转换最初用于将 XML 配置的属性设置到 bean 时将文本内容转换为对象字段的具体类型。


由于 java bean 规范已经有了一个 PropertyEditor 接口可用于类型转换,因此 Spring 最初复用了这个接口。


不过后来 Spring 官方发现这个接口的职责不够清晰,除了类型转换还有一些 GUI 程序使用的方法,另外就是只局限于将字符串转换为其他类型,而不能进行任意类型的转换,因此 Spring 3.0 提供了新的接口 ConversionService 替换 PropertyEditor,这个接口允许任意类型之间的转换。


类型转换常发生在数据绑定期间,除了 XML 配置的类型转换,另一处使用场景仍然是将 HTTP 请求数据的字符串形式转换为具体的类型。


如果你想了解更多关于类型转换的内容,可以参见《Spring 核心特性之类型转换(PropertyEditor、ConversionService)》。


校验(bean validation)


校验的目的是避免客户端传入不合法的数据,为了避免程序中充斥着大量的校验代码,Java 社区提出了 JSR-303 规范用于数据校验,不过这套规范是指定义应该如何校验,并涉及到实现。


通常我们使用的 bean validation 的实现是 Hibernate,Spring 官方将 JSR-303 规范与 Spring 生态整合到一起,大大简化了校验的使用方式。


更多校验相关内容,也可以参考 《Spring 参数校验最佳实践及原理解析》。


资源管理(resource)


在 Java 中,资源的表现形式有多种,如 URL、InputStream、File,这些资源又可以分布在本地、类路径、网络,加载方式也多种多样,Spring 将其整合到一起,使用 Resource 统一表示抽象的资源,简化了对资源的操作方式。


更多资源相关内容,可以参考 《Spring 资源管理 (Resource)》。


事件(event)


Spring 事件基于 Java 标准的观察者模式,Spring 在应用上下文的生命周期中会发布一些事件通知用户,此外 Spring 还允许用户发送和监听自定义的事件,而且发布的事件还支持泛型。如果想要解耦代码,也可以考虑使用 Spring 的事件。


更多 Spring 事件处理,可以参考《Spring 事件处理机制详解,带你吃透 Spring 事件》


表达式(spring expression)


Spring 的表达式类似于在 JSP 中使用的表达式,直接使用的场景也不太多,在框架中使用可能会多一些,例如缓存框架可以通过方法上注解属性中的 Spring 表达式读取缓存的 key,进一步做 CURD,这块内容我暂为总结,后续将会补上。


总结


本文主要对 Spring 核心特性进行了简单的介绍,由于其涉及的内容较多,感兴趣的同学可以参考我前面的文章。


目录
相关文章
|
1月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
48 4
|
1月前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
38 0
|
3月前
|
安全 前端开发 Java
随着企业应用复杂度提升,Java Spring框架以其强大与灵活特性简化开发流程,成为构建高效、可维护应用的理想选择
随着企业应用复杂度提升,Java Spring框架以其强大与灵活特性简化开发流程,成为构建高效、可维护应用的理想选择。依赖注入使对象管理交由Spring容器处理,实现低耦合高内聚;AOP则分离横切关注点如事务管理,增强代码模块化。Spring还提供MVC、Data、Security等模块满足多样需求,并通过Spring Boot简化配置与部署,加速微服务架构构建。掌握这些核心概念与工具,开发者能更从容应对挑战,打造卓越应用。
43 1
|
3月前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
25天前
|
XML 缓存 Java
搞透 IOC、Spring IOC ,看这篇就够了!
本文详细解析了Spring框架的核心内容——IOC(控制反转)及其依赖注入(DI)的实现原理,帮助读者理解如何通过IOC实现组件解耦,提高程序的灵活性和可维护性。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
|
2月前
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
225 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
|
17天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
31 0
|
2月前
|
XML Java 测试技术
spring复习01,IOC的思想和第一个spring程序helloWorld
Spring框架中IOC(控制反转)的思想和实现,通过一个简单的例子展示了如何通过IOC容器管理对象依赖,从而提高代码的灵活性和可维护性。
spring复习01,IOC的思想和第一个spring程序helloWorld
|
1月前
|
Java Spring 容器
Spring IOC、AOP与事务管理底层原理及源码解析
【10月更文挑战第1天】Spring框架以其强大的控制反转(IOC)和面向切面编程(AOP)功能,成为Java企业级开发中的首选框架。本文将深入探讨Spring IOC和AOP的底层原理,并通过源码解析来揭示其实现机制。同时,我们还将探讨Spring事务管理的核心原理,并给出相应的源码示例。
130 9
|
1月前
|
存储 开发框架 Java
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
文章详细介绍了Spring、IOC、DI的概念和关系,解释了控制反转(IOC)和依赖注入(DI)的原理,并提供了IOC的代码示例,阐述了Spring框架作为IOC容器的应用。
32 0
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
下一篇
无影云桌面