Spring框架核心组件设计理念及设计模式分析

2023-11-24 10:40

本文主要是介绍Spring框架核心组件设计理念及设计模式分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Spring框架部分设计理念及设计模式分析

Spring是目前最优秀的框架之一,本文介绍Spring的总体架构以及特性,然后主要针对Spring中部分组件分析其设计理念和设计模式。


Spring总体架构

Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。在Spring框架中,总共有十几个组件,总体架构图如图所示:

Spring总体架构图

Spring采用的是分层架构,Core Spring Container为Spring的核心,实现了基于IoC的bean管理容器。在IoC和AOP基础上,扩展了数据层和Web层。


Spring中IoC(DI)和AOP的理解

IoC

IoC(Inversion of Control)即控制反转,它是一种设计思想。在传统的Java编程思想中,我们会直接在Java对象内部通过new方法直接创建对象,导致程序对象紧密耦合。而在Spring中,创建对象的权限交由IoC容器处理,当程序需要对象时,通过向IoC容器获取得到对象的引用。总的来说,IoC容器控制了外部资源获取,容器查找及注入依赖对象,对象只是被动的接受依赖对象,所以称之为控制反转。

DI

DI(Dependency Injection)即依赖注入,它指的是在Spring中,不同对象之间的依赖关系由运行时通过容器进行确定,简单地说,就是容器在运行时动态地将依赖关系注入到组件中,向某个对象提供它所需要的其他对象。。依赖注入的使用可以提高组件的重用性。应用程序依赖于IoC容器来提供对象需要的外部资源。

IoC与DI

那么IoC和DI两个名词又有什么区别呢?从我的理解来看,它们只是对于Spring采用容器管理Java对象的同一件事不同层面的表示,IoC所阐述的是一种思想,指的是Spring将传统的使用new方法直接创建Java对象改为通过IoC容器获取Java对象,IoC容器控制的对象创建的权利,降低了Java对象之间的依赖关系;DI则大多指得是实现IoC的方式,通过依赖注入实现控制反转。其实DI是2004年大师级人物Martin Fowler针对“控制反转“给出了的新的名字,相对“控制反转“而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。

Aop

Aop(Aspect Oriented Programming)即面向切面编程,它是针对与OOP(Object Oriented Programming)即面向对象编程的补充。”切面”,简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任。OOP是针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分。Aop是针对业务处理过程中的切面进行提取,它所面对的是处理过程的某个步骤或阶段,利用”横切”技术,剖解开封装的对象内部,将影响了多个类的公共行为封装到一个可重用模块(即切面),减少系统的重复代码,降低模块之间的耦合度,有利于未来的可操作性和可维护性。Aop的应用场景有日志记录,性能统计,安全控制,事务处理,异常处理等。

Aop把系统分为核心关注点和横切关注点。核心关注点是业务处理的主要流程,横切关注点是与业务处理流程关系不大的补充其他补充功能。横切关注点的一个特点是经常发生在多个核心关注点上,而且各处处理方式基本相似,比如权限认证、日志、事务。Aop的作用在于分离系统中的核心关注点和横切关注点。

Aop采用了Proxy模式,例如JdkDynamicAopProxy和Cglib2AopProxy,用到了JDK的动态代理模式。

这里写图片描述

$Proxy是创建的代理对象,Subject是抽象主题,代理对象是通过Invocatio-nHandler来持有对目标对象的引用。除了实现被代理对象的接口外,还会有org.springframework.aop.SpringProxy和org.springframework.aop.fram-ework.Advised两个接口。


Spring部分组件及其设计模式

Bean组件

在Spring中,Bean类似于java面向对象编程中的Object,Spring把对象包装在Bean中而达到对对象管理以及一些额外操作的目的。Bean组件在Spring的org.springframework.beans包下。Bean 组件主要包括三项功能:Bean定义,Bean创建以及Bean解析。在使用Spring框架时,用户只需对Bean进行定义,对于Bean的创建和解析由Spring负责(对用户是透明的)。

Bean在创建时采用的是工厂模式,类图如图1所示,它的顶级接口是BeanFactory,它是典型工厂方法模式的接口,有三个子接口继承至该接口,分别为ListableBeanFactory、HierarchicalBeanFactory和Autowire-CapableBeanFactory。虽然最终的实现类实现了之前接口中的所有方法,但是对于每一个接口来说,它们都有各自使用的场合,主要是为了区分在Spring 内部对象的传递和转化过程中,对对象的数据访问所做的限制。例如ListableBean-Factory 接口表示这些 Bean 是可列表的,它可以列出工厂可以生产的所有实例;HierarchicalBeanFactory 表示的是这些 Bean 是有继承关系的,也就是每个 Bean 有可能有父 Bean;AutowireCapableBean-Factory 接口定义 Bean 的自动装配规则,根据类定义BeanDefinition装配Bean、执行前、后处理器等。这四个接口共同定义了 Bean 的集合、Bean 之间的关系、以及 Bean 行为。

Bean组件类图

Bean的定义完整地描述了在Spring配置文件中定义的<bean/>节点中所有的信息,包括各种子节点。当 Spring 成功解析一个<bean/>节点后,在 Spring 的内部它被转化成 BeanDefinition 对象,以后所有的操作都是对这个对象完成的。

这里写图片描述

Bean 的解析过程非常复杂,功能被分的很细,因为需要被扩展的地方很多,必须保证有足够的灵活性,以应对可能的变化。Bean 的解析主要就是对 Spring 配置文件的解析。

这里写图片描述

Context组件

Context 组件源代码位于 Spring 的 org.springframework.context 包下,Context 组件在 Spring 中的实际上就是给 Spring 提供一个运行时的环境,用以保存各个对象的状态。

这里写图片描述

ApplicationContext 是 Context 的顶级父类,它除了能标识一个应用环境的基本信息外,他还继承了五个接口,这五个接口主要是扩展了 Context 的功能。ApplicationContext继承了BeanFactory,说明了Spring容器中运行的主体对象是Bean,另外ApplicationContext继承了ResourceLoader接口,使得ApplicationContext可以访问到任何外部资源。

ApplicationContext的子类主要包含两个:

  1. ConfigurableApplicationContext表示该种类型的Context是可修改的,也就是在构建Context时用户可以动态添加或修改已有的配置信息,它又有多个子类,其中最经常使用的是可更新的Context,即
    AbstractRefreshableApplicationContext类。

  2. WebApplicationContext是为web准备的Context,它可以直接访问到ServletContext,通常情况下,这个接口使用的少。

再往下分就是按照构建Context的文件类型,接着就是访问Context的方式。这样一级一级构成了完整的Context等级层次。

总体来说ApplicationContext必须要完成以下几件事:

  • 标识一个应用环境
  • 利用BeanFactory创建Bean对象
  • 保存对象关系表
  • 能够捕获各种事件

Context作为Spring的IoC容器,基本上整合了Spring的大部分功能,或者说是大部分功能的基础。

Core组件

Core组件一个重要组成部分就是定义了资源的访问方式,把资源都抽象成一个接口,本节内容主要介绍该部分内容。

Resource接口封装了各种可能的资源类型,对使用者屏蔽了文件类型的不同。Resource接口继承了InputStreamSource接口,接口中的getInput-Stream方法,返回的是InputStream类。这样所有的资源都被可以通过InputStream这个类来获取,所以屏蔽了资源的提供者对文件类型不同的感受。另外还有一个问题就是加载资源的问题,也就是资源的加载者要统一,在Spring中这个任务是由ResourceLoader接口完成,它屏蔽了所有的资源加载者的差异,只需要实现这个接口就可以加载所有的资源,它的默认实现是DefaultResourceLoader。


这篇关于Spring框架核心组件设计理念及设计模式分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/421783

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory