本文主要是介绍Spring 体系结构,核心理念,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
- spring概述
- spring的设计目标
- spring的设计理念
- spring的优缺点
- spring的体系结构
- spring的核心组件
- core模块的Resource
- beans模块的BeanDefinition
- beans模块的BeanFactory
- context模块的ApplicationContext
- spring的2大特性 | 核心
- IoC 控制反转
- IoC的优点
- IoC常见的实现方式
- IoC、DI的关系
- spring IoC的实现机制
- DI的实现原理
- AOP 面向切面编程
- aop的优点
- aop常见的应用场景
- aop中的主要名词|概念
- aop的织入时机 | 方式
- spring提供的2种aop实现
- spring中的2个核心概念
- bean
- 传统的java bean
- spring bean
- 容器
- spring容器提供的功能
- spring中2种容器 | 容器的2个核心接口
- spring容器的实现原理
- spring中用到的设计模式
相关问题
- 什么是spring?谈谈你对spring的理解
- spring有什么优缺点
- spring的体系结构是怎样的?spring有哪些模块?
- spring中有哪些核心组件?
- spring有什么特性?
- spring是怎么实现aop的?spring有几种方式实现aop?spring aop的原理是什么?
- spring中用到了哪些设计模式?
- spring中有哪几种配置方式?
说明
- 本文使用的spring源码版本是 5.3.x
- 源码的一些方法上标注得有 spring的 @Nullable 注解,提醒开发者方法返回值可以为null。为了节省篇幅,我把注释和方法上标注的 @Nullable 都去了。
spring概述
spring的设计目标
设计目标 | 设计初衷
- 解决企业级应用开发的复杂性,即简化Java开发
- 为开发者提供一个一站式轻量级应用开发平台;
为了降低Java开发的复杂性,Spring采取了以下4种关键策略
- 基于POJO的轻量级和最小侵入性编程;
- 通过依赖注入和面向接口实现松耦合;
- 基于切面和惯例进行声明式编程;
- 通过切面和模板减少样板式代码。
spring的设计理念
BOP,bean oriented programming 面向bean编程
- bean是spring中的核心概念,是spring应用中的核心java对象;
- spring本身围绕bean进行设计,使用 BeanDefinition 封装bean的定义,使用 BeanFactory 获取bean的实例;
- spring容器其实是 spring bean container 是bean的容器,负责bean的实例化、装配、管理;
- 使用spring进行开发其实是面向bean进行编程,开发的主要任务是编写、配置bean。
spring的优缺点
优点|好处
- 轻量,非侵入式设计,降低代码耦合度
- 提供了IoC容器,开发者不必关心对象的创建过程、对象间复杂的依赖关系
- 支持AOP,把业务逻辑和横切逻辑分离开来
- 是一站式解决方案,提供了测试、web、数据访问、事务管理、异常处理等功能,简化了开发,降低了开发难度
- 强大的整合能力,可以和很多优秀框架无缝整合
缺点
- spring的设计初衷是轻量级的开发框架,但给人一种大而全的感觉
- 依赖反射,框架本身大量使用反射,很影响性能,且破坏类封装性。比如创建bean实例时通过反射调用构造方法创建实例,实现@Value、@Autowired时通过反射给字段赋值、调用方法注入依赖,
- aop使用大量使用动态代理,在运行时动态创建代理,很影响性能
spring的体系结构
spring是轻量级的一站式开发框架,以 IoC、AOP 为核心,集成了Test模块来支持测试,集成了 Data Access 数据访问模块来操作数据源,集成了Web模块来支持web开发。
spring的5大版块|功能
- Test 测试模块:提供对测试的支持
- Core Container 核心容器模块:实现了spring容器,主要提供IoC/DI功能
- AOP模块:提供对aop的支持,包括spring aop、aspectj 2种实现方式
- Data Access/Integration 数据访问/集成模块:提供对数据源操作的支持,包括对jdbc、orm映射框架、xml解析、消息队列、事务管理的支持
- Web模块:提供对web应用的支持。在目前最新的5.x版本中,Web模块已经废弃了 Portlet 组件,同时增加了用于异步响应式处理的 WebFlux 组件。
Core Container 核心容器模块分为4个小模块
- Beans:提供BeanDefinition、BeanFactory,实现了容器的核心功能 IoC
- Core:提供Resource,集成了对多种资源的访问、解析能力
- Context:建立在Beans、Core模块的基础上,实现了高级容器ApplicationContext,用于暴露给开发者使用,以及整合其它框架时对第三方库提供支持
- SpEL:提供对Spring EL(表达式语言)的支持
spring的核心组件
spring的核心是bean,核心组件都是围绕bean进行设计的
core模块的Resource
定义对资源的访问,用于加载资源
public interface Resource extends InputStreamSource {boolean exists();default boolean isReadable() {return exists();}default boolean isOpen() {return false;}default boolean isFile() {return false;}URL getURL() throws IOException;URI getURI() throws IOException;File getFile() throws IOException;default ReadableByteChannel readableChannel() throws IOException {return Channels.newChannel(getInputStream());}long contentLength() throws IOException;long lastModified() throws IOException;Resource createRelative(String relativePath) throws IOException;String getFilename();String getDescription();}
Resource接口定义的是通用的资源访问,屏蔽了资源的来源、格式的不同,常见的最终实现类如下
- UrlResource:实现了对网络资源的访问
- ClassPathResource:实现了对classpath中的资源访问
- FileSystemResource:实现了对文件系统中的资源访问
- InputStreamResource:实现了对输入流中的资源访问
- ByteArrayResource:实现了对字节数组中的资源访问
beans模块的BeanDefinition
用于描述bean的定义、元数据、bean之间的依赖关系。
xml文件或注解定义的bean会被转换为BeanDefinition实例,存储在 BeanFactory 中。
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {//scope常量String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;//role常量,标识bean在系统中的角色int ROLE_APPLICATION = 0; //开发自定义的beanint ROLE_SUPPORT = 1; //spring中对外提供支持、整合能力,暴露给开发使用的beanint ROLE_INFRASTRUCTURE = 2; //基础设施,spring中的基础bean//父BeanDefinition的namevoid setParentName(@Nullable String parentName);String getParentName();//BeanClassName,bean对应的java类的类名void setBeanClassName(@Nullable String beanClassName);String getBeanClassName();//作用域void setScope(@Nullable String scope);String getScope();//懒加载void setLazyInit(boolean lazyInit);boolean isLazyInit();/** 依赖关系。dependsOn 是当前bean依赖的其它bean的name。在getBean()中:合并BeanDefinition修改后,会先通过getBean()获取dependsOn依赖的实例,保证所有dependsOn依赖都已经实例化,再根据bean的scope调用createBean()创建bean实例 */void setDependsOn(@Nullable String... dependsOn);String[] getDependsOn();/** 自动装配时是否优先选用。有多个可用实例时,会优先使用primary为true的bean */void setPrimary(boolean primary);boolean isPrimary();//要使用的 FactoryBean 的namevoid setFactoryBeanName(@Nullable String factoryBeanName);String getFactoryBeanName();//要使用的 FactoryMethod 的namevoid setFactoryMethodName(@Nullable String factoryMethodName);String getFactoryMethodName();//构造器的参数表,包括参数名、参数类型、参数值ConstructorArgumentValues getConstructorArgumentValues();default boolean hasConstructorArgumentValues() {return !getConstructorArgumentValues().isEmpty();}//属性值,包括属性名、属性值MutablePropertyValues getPropertyValues();default boolean hasPropertyValues() {return !getPropertyValues().isEmpty();}//初始化方法void setInitMethodName(@Nullable String initMethodName);String getInitMethodName();//销毁方法void setDestroyMethodName(@Nullable String destroyMethodName);String getDestroyMethodName();//bean的角色,比如spring本身的bean、第三方框架的bean、开发自定义的beanvoid setRole(int role);int getRole();//bean的描述文字。对bean进行简单介绍,主要给其他开发看void setDescription(@Nullable String description);String getDescription();//一些判断方法。可以把抽象类标识为bean,但抽象类本身是不会实例化的。boolean isSingleton();boolean isPrototype();boolean isAbstract();//bean对应的Resource的描述信息String getResourceDescription();/** 获取原始的BeanDefinition。一个bean可以用多种方式共同配置,在加载过程中会合并BeanDefinition的修改,这个bean最先解析提取到的BeanDefinition即为原始BeanDefinition */BeanDefinition getOriginatingBeanDefinition();}
beans模块的BeanFactory
BeanFactory是容器的顶级接口,定义IoC容器的基础功能,包括bean的创建、装配、获取、管理
context模块的ApplicationContext
spring加载资源、配置得到Resource,根据Resource创建Context。
context:背景、环境、上下文,融合了spring容器中的各种资源,开发者、第三方类库通过与context交互来操作spring容器、获取容器中的资源,相当于spring营造的的应用环境、spring对外暴露的util。
ApplicationContext 就是context模块中的。
spring的2大特性 | 核心
IoC 控制反转
IoC:Inversion of Control,控制反转,传统应用是由开发者在代码中控制对象的创建,IoC是将对象创建的控制权交给IoC容器,由IoC容器负责对象的创建、管理。
IoC的优点
- 避免在各处使用new来创建实例,降低类之间的耦合度,易于维护
- 由容器负责创建类的实例、注入所需依赖,开发者无需关心对象创建的细节、对象间复杂的依赖关系,简化了应用开发、降低了开发难度。
IoC常见的实现方式
- DL:依赖查找,bean主动到IoC容器中查找所需的依赖
- DI:Dependency Injection,依赖注入,由IoC容器主动给bean注入所需的依赖
DL是EJB时代的实现方式,现在主流的实现方式是DI
IoC、DI的关系
IoC是一种编程思想,DI是IoC的一种实现方式
spring IoC的实现机制
镜像问题
- spring IoC的实现原理|机制
- spring IoC是怎么实现的
核心点:工厂模式+反射机制+工厂方法
主要采用工厂模式实现,通过 BeanFactory 的 getBean() 方法获取所需实例,如果实例不存在,会调用 createBean() 主动创建所需实例。
创建实例可以使用构造方法方式,实质是通过反射机制调用构造方法创建实例;也可以通过工厂方法创建实例。
DI的实现原理
镜像问题:spring是如何实现DI的?
通过 getBean() 获取bean实例时,如果没有对应的实例,会调用 createBean() 创建bean实例。
在填充属性阶段,根据注入模式选择 autowireByName() 或 autowireByType() 进行注入,在注入过程中使用 getBean() 获取所需依赖。
AOP 面向切面编程
aop: Aspect-Oriented Programming 面向切面编程,是面向对象编程的一种补充, 在不改变原有业务逻辑的基础上添加额外的处理。
aop的优点
把和业务逻辑无关的横切逻辑剥离出来,不与业务代码耦合在一起,减少系统中的重复代码,使系统变得高内聚、低耦合,更易维护。
aop常见的应用场景
- 记录日志、流水
- 事务管理
- 安全检查、权限控制
- 更新缓存
aop中的主要名词|概念
- Aspect:切面,横切逻辑的代码实现,通常是一个类,定义了切入点、通知
- Advice:通知、增强,可以看做把切面按作用时机的划分
- Target:目标,要应用切面的业务对象、类
- JointPoint:连接点,目标类|对象中的所有方法都可以作为连接点
- PointCut:切入点,目标类|对象中实际应用切面 | 切面的方法
- Weaving:织入,把切面应用到连接点以实现增强的过程
aop的织入时机 | 方式
- 编译时织入:通过修改编译生成的字节码实现,需要借助专门的编译器,缺点是编译就已确定要增强的对象、要应用的增强,不够灵活
- 编译后织入:生成字节码之后、类加载之前,使用工具对字节码进行处理以应用增强
- 类加载时织入:使用自定义的类加载器,在类加载时应用增强
- 运行时织入:在运行时通过动态代理生成代理,使用代理代替目标对象进行操作
spring提供的2种aop实现
1、spring aop
spring早期版本提供的aop实现,只提供了简单的aop实现,局限多,只能对spring容器中的bean应用增强,只能对方法进行增强。
spring aop默认使用的代理策略、织入时机
- spring aop基于动态代理实现,可以指定要使用的动态代理类型,在运行时进行织入
- 未指定要使用的动态代理类型时,默认使用jdk动态代理,如果不满足jdk动态代理的使用条件(目标类没有实现接口),则使用cglib代理。
spring aop的实现原理
- spring aop是基于动态代理实现的,在运行时动态生成代理
- 默认使用jdk动态代理,如果目标没有实现接口,则使用cglib代理
2、aspectj
aspectj是一个专业的aop框架,提供了一套完整的aop解决方案,在spring的后续版本中集成aspectj。aspectj比spring aop更加强大,可对所有域中的对象进行增强,可对字段、方法、构造方法等内容进行增强。
aspectj的织入时机、原理
- aspectj支持在编译时、编译后、类加载时进行织入
- 通常使用编译时织入,需要借助AspectJ 编译器 (ajc) ,基于字节码操作,使用的是静态代理。
性能比较
- aspectj通常使用编译时织入,在编译时就可以确定增强,使用时直接生成代理
- spring aop是在运行时动态生成代理,性能比aspectj差,在大量使用aop的项目中性能差距尤其明显
aspectj的应用范围更广、性能更好,比spring aop更强大,更常用,也更推荐使用aspectj。
spring中的2个核心概念
bean
常见问题
- java bean、spring bean的区别
- 什么是spring bean
传统的java bean
简单来说就是实体类,用来封装对象,包含成员属性和对应的getter、setter方法。
spring bean
bean是spring中的核心概念,使用spring其实是面向bean编程,开发的主要任务就是编写、配置bean。
spring中的bean有2层含义
- 可以看成 BeanDefinition 实例
- 也可以看成由spring容器负责创建、装配、管理的 java 对象
容器
实现了IoC的容器都可以叫做IoC容器,spring容器只是IoC的一种实现,只是IoC容器中的一种,spring容器 ≠ IoC容器。
spring容器提供的功能
- 依赖注入,这是最重要的功能
- 自动装配
- 可以设置回调方法,以及bean的初始化方法、销毁方法
spring中2种容器 | 容器的2个核心接口
相关问题:BeanFactory、ApplicationContext的联系与区别
BeanFactory
- 功能:提供IoC容器的基础功能,负责创建bean实例、注入所需依赖,是获取bean实例的工厂、低级容器
- 定位:面向spring框架本身,主要在spring框架内部使用
- bean的实例化时机:低级容器启动时,不会实例化bean,调用getBean()从容器中获取bean实例时才会实例化对应的bean
- 注册方式:支持 BeanPostProcessor、BeanFactoryPostProcessor ,但需要手动注册
ApplicationContext
- 功能:在BeanFactory的基础上继承了多个接口,集成了更多功能,几乎包括了应用中的各种资源,是context 应用运行的环境、高级容器,而非简单的获取bean实例的工厂
- 定位:面向spring的使用者,主要提供给spring的使用者进行调用
- bean的实例化时机:高级容器启动时,会实例化所有单例(懒加载的单例除外),这也造成了高级容器启动速度比低级容器慢得多
- 注册方式:支持 BeanPostProcessor、BeanFactoryPostProcessor ,高级容器启动时会自动注册
一般把 BeanFactory 称为低级容器、IoC 容器,把 ApplicationContext 称为应用上下文、高级容器,通常说的Spring容器是指高级容器 ApplicationContext 。
spring容器的实现原理
镜像问题
- spring是怎么实现容器的
- spring是如何设计容器的
- spring容器的实现机制 | 原理
spring提供了2个容器
- BeanFactory:低级容器,实现了容器的基础功能IoC,负责bean实例的创建、依赖注入
- ApplicationContext:高级容器,在BeanFactory的基础上集成了更丰富的功能,是整个应用的运行环境、上下文。
DefaultListableBeanFactory整合了BeanFactory体系的主要接口,功能齐全,常作为低级容器的实现。
AbstractApplicationContext 实现了加载|刷新配置的 refresh() 方法,是 ApplicationContext 的主要实现类,也是高级容器最终实现类的共同基类。
高级容器中内置了低级容器,通过内置的低级容器提供IoC容器的基础功能。
spring中用到的设计模式
- 工厂模式:通过BeanFactory创建bean实例
- 单例模式:bean默认是单例的
- 代理模式:spring aop通过动态代理实现
- 模板方法:抽取特定场景中经常复用的代码,解决重复代码多的问题,比如JdbcTemplate、RestTemplate, JmsTemplate, JpaTemplate
- 观察者模式:主题对象的状态发生改变时,通知订阅了该主题的所有对象,Spring的事件驱动模型(listener 监听器)就是观察者模式的经典应用。
- 适配器模式:比如springmvc中的处理器适配器 HandlerAdapter,spring aop中用于适配Advice的AdviceAdapter
- 策略模式
这篇关于Spring 体系结构,核心理念的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!