Spring Framework 历经2004年发布的 1.0版本到 2018年的 5.0版本,已经逐步发展成为一个功能强大、灵活多样的开发框架,被广泛应用于企业级Java应用程序的开发。
并且Spring Framework在2022年底还发布了 6.0新版本的相关消息,Spring Framework 6.0将继续推动Spring生态系统的发展,提供更加先进、灵活和高效的开发工具,以满足不断变化的业务需求和技术趋势。
下面是各个版本的Spring Framework的主要功能:
1.x 版本:主要提供了 IoC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)功能,并提供了对JDBC访问和事务管理的支持;
2.x 版本:在1.x版本的基础上,引入了注解支持、Java 5特性支持,增加了对Web应用程序的支持,包括MVC框架和Web服务的支持;
3.x 版本:支持 Java EE 6标准、RESTful风格的Web服务支持、Spring Expression Language(SpEL) 等新功能;
4.x 版本:增加了对Java 8新特性的支持,包括Lambda表达式和Stream API的支持等,提供Groovy语言支持、WebSocket支持 等新功能;
5.x 版本:引入了 响应式编程模型,提供了对 Reactive Streams和 WebFlux的支持,同时也支持Java 9和Java 10的新特性;
6.x 版本(即将发布):支持Java 17中的新特性和改进,采用模块化的架构将核心框架和各种扩展模块分离,支持更多的数据访问技术(例如NoSQL数据库、图形数据库等)等。
Spring Framework是一个开源的Java应用程序框架,最初由Rod Johnson在2003年创建。框架旨在通过丰富的特性和功能,帮助开发人员构建高效、灵活、可维护的应用程序。Spring框架提供了许多功能,包括依赖注入、AOP、JDBC集成、事务管理、Web应用程序开发等。
Spring框架的核心部分有:
IoC容器:Spring的IoC容器负责管理应用程序中的对象,并处理它们之间的依赖关系。开发人员只需定义对象和它们之间的关系,Spring容器就会自动创建和管理这些对象。这样可以将应用程序的逻辑与对象的创建和管理分离,提高了代码的可重用性和可维护性;
面向切面编程(AOP):通过AOP,可以将横切关注点(如日志记录、事务管理、安全性等)与业务逻辑分离,使得应用程序的代码更加简洁、可读性更高;
JDBC集成:Spring框架提供了JDBC模板,简化了JDBC编程,使得开发人员可以更加方便地访问和操作数据库;
事务管理:Spring框架提供了一种统一的事务管理机制,可以管理多个事务资源,如数据库连接、JMS队列等。开发人员可以通过声明式事务管理,将事务管理逻辑与业务逻辑分离;
Web应用程序开发:Spring框架提供了一个MVC框架,用于开发Web应用程序。MVC框架提供了控制器、视图、模型等组件,使得开发人员可以更加方便地开发Web应用程序。
除了以上主要特点外,Spring框架还提供了许多其他的功能,如集成测试、缓存、安全性、远程调用等。Spring框架的目标是提供高效、灵活、可重用的代码,使得Java开发人员可以更加方便地开发高质量的应用程序。
👉 作为一款优秀的开发框架,Spring Framework有以下优点:
📃 当然,凡事都有两面性,即便优秀如Spring Framework 也不例外,它也有以下几个缺点:
Spring Framework主要包含以下模块:
这些模块为应用程序开发提供了广泛的支持,使得开发者可以快速地构建高质量、可维护的应用程序。
Spring配置文件是指在Spring框架中用来配置应用程序组件的XML文件。
applicationContext.xml是Spring的默认配置文件,当容器启动时找不到指定的配置文档时,将会尝试加载这个默认的配置文件。
Spring配置文件通常存储在应用程序的classpath路径下,并由Spring框架在应用程序启动时加载。除了XML格式,Spring还支持其他格式的配置文件,如JavaConfig和GroovyConfig等。
它通常包含了Spring应用程序中各种对象的定义和它们之间的关系,例如 bean的定义、依赖注入、AOP配置、数据源配置等。Spring框架使用这些配置文件来实例化应用程序中的组件,并将它们装配在一起以构建完整的应用程序。
Bean定义:定义Spring中的各个组件和对象,包括数据源、事务管理器、服务层、DAO层等。可以通过配置文件中的bean标签进行定义和配置;
属性注入:配置Bean中的属性,包括基本类型、引用类型、集合类型等。可以通过配置文件中的property标签进行配置;
依赖注入:配置Bean之间的依赖关系,包括构造函数注入和setter方法注入两种方式。可以通过配置文件中的 constructor-arg和 property标签进行配置;
AOP配置:配置Spring框架中的AOP(面向切面编程)功能,包括切面、切点、通知等。可以通过配置文件中的aop命名空间进行配置;
MVC配置:配置Spring框架中的MVC(模型-视图-控制器)功能,包括控制器、视图解析器、视图渲染器等。可以通过配置文件中的mvc命名空间进行配置;
数据源配置:可以配置数据库连接池、数据库驱动、数据库用户名密码等信息。可以通过配置文件中的datasource标签进行配置;
事务配置:可以配置Spring框架中的事务管理器、事务注解等信息。可以通过配置文件中的tx命名空间进行配置。
Spring配置文件的编写需要遵循一定的规则和约定,可以通过Spring容器来读取和解析配置文件,并创建相应的Bean对象和组件。配置文件的正确性和合理性对于Spring应用程序的正常运行和性能表现至关重要。
🔍 关于spring的配置文件的更详细的各项配置的详情,可以参考这篇文章:
spring配置文件详解
Spring IOC(Inversion of Control,控制反转)是Spring框架的核心思想,它的实现手段是通过依赖注入(DI,Dependency Injection) 的方式来实现。
在传统的应用程序中,对象之间的依赖关系是由程序代码在对象内部通过new关键字等方式硬编码而成。而在Spring框架中,对象之间的依赖关系是由Spring容器在运行期间动态地通过反射机制等技术来进行注入 的。对于Spring而言,就是由Spring来控制对象的生命周期和对象之间的关系。
具体来说,Spring IOC的实现原理包括以下几个步骤:
通过IOC和DI的方式,Spring框架实现了应用程序中各个组件之间的解耦,使得应用程序更加灵活和易于扩展。
Spring 容器是 Spring 框架的核心。容器创建对象,将它们装配在一起,配置它们并管理它们的完整生命周期。
Spring 容器使用依赖注入来管理组成应用程序的组件。容器通过读取提供的配置元数据来接收对象进行实例化,配置和组装的指令。该元数据可以通过 XML,Java 注解或 Java 代码提供。
在Spring中IOC容器的主要表现形式是 BeanFactory和 ApplicationContext这两个接口。这两个接口的具体实现类就可以看成是IOC容器在Spring中的具体体现。
BeanFactory提供了最基本的IOC和依赖注入功能,ApplicationContext继承了BeanFactory,在BeanFactory的基础上添加了很多新功能,主要包括国际化、事件分发机制(ApplicationEvent)、资源访问(Resource)等功能。在实际的开发过程中,一般都会选择ApplicationContext系列的容器实现。
依赖注入(DI,Dependency Injection)是 spring 框架核心 IoC 的具体实现手段或方式。所谓依赖注入,即在运行期由容器将依赖关系注入到组件之中。
就是在运行期,由Spring根据配置文件,将其他对象的引用通过组件的提供的setter方法进行设定。
Spring 大量引入了Java 的Reflection机制,通过动态调用的方式避免硬编码方式的约束,并在此基础上建立了其核心组件BeanFactory,以此作为其依赖注入机制的实现基础。
在Spring框架中,可以通过以下方式实现依赖注入:
构造器注入(Constructor Injection):通过构造方法来完成对依赖的注入。
通过添加@Component 或@Service 等注解使 bean受Spring容器管理,再将依赖以参数形式传递给构造函数。
@Service public class UserServiceImpl implements UserService { private final UserMapper userMapper; @Autowired public UserServiceImpl(UserMapper userMapper) { this.userMapper = userMapper; } }
Setter方法注入(Setter Injection):在bean中创建setter方法,并在该方法上使用@Autowired、@Resource等注解,Spring会自动调用这些setter方法并注入需要的依赖项;
@Service public class UserServiceImpl implements UserService { private UserMapper userMapper; @Autowired public void setUserMapper(UserMapper userMapper) { this.userMapper = userMapper; } }
属性注入(Field Injection,也叫字段注入或变量注入):在bean中定义成员变量并将其标记为@Autowired或@Resource等注解,Spring会自动将相应的依赖对象注入到这些字段上;
@Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; //... }
以上就是各种依赖注入的实现方式。其优势及缺点如下:
实现方式 | 优点 | 缺点 |
---|---|---|
属性注入 | 方式简单,代码简洁 | 注入对象不能用final修饰; 可能会导致循环依赖,启动不报错,使用时才报错; 存在潜在隐患,不调用将无法发现 NullPointException异常; |
构造器注入 | 注入对象可以使用final修饰; 若存在循环依赖,spring项目启动的时候就会报错; 通过强制指明依赖注入来保证这个类的运行,防止NullPointerException; | 当有多个对象需要注入时,构造函数的代码臃肿; |
Setter方法注入 | 依赖注入中使用的依赖是可选的,注入的依赖可以为 null; 允许在类构造完成后重新注入; | 注入对象不能使用final修饰; |
其中,建议使用构造方法注入和setter方法注入,因为它更为清晰明了且不会导致循环依赖问题。而属性注入则容易引发一些设计和测试问题。
在Spring框架中,Bean作用域(scope)指的是在不同环境下创建和管理Bean时的生命周期。
一个Bean实例会有自己的作用域,而总共有以下5种的作用域情况:
Singleton(单例):一个IoC容器中只能存在一个实例,不同容器之间可以有不同的实例。这种bean范围是默认的,这种范围下不管接受到多少个请求,每个容器中只会有一个bean的实例;
Prototype(原型):每个请求都会创建一个新的实例,每次调用getBean()都会返回一个新的对象。这意味着每个客户端将获得一个新的原型实例,并且与之前连接的客户端没有关系;
Request(请求):仅适用于WebApplicationContext上下文中,表示为每个HTTP请求创建一个新的Bean实例。因此,对于同一次HTTP请求而言,任何对Bean的请求都将返回同一个Bean实例。然而,不同的HTTP请求将产生不同的Bean实例;
Session(会话)也仅适用于WebApplicationContext上下文中,表示为每个HTTP会话创建一个新的Bean实例。同一会话中的多个请求将共享同一个Bean实例;
GlobalSession(全局会话):仅适用于web应用程序,表示为每个全局HTTP会话创建一个新的Bean实例,通常只在使用Spring Portlet MVC时才使用。如果部署在Servlet环境下,该作用域没有区别于Session。
在实际应用中,正确选择和使用适当的作用域很重要。在大多数情况下,Singleton是最合适和高效的选项,也是默认作用域,它创建一个对象并在容器内共享该对象。Prototype每次请求都会创建一个新的实例,因此它可以防止线程安全问题。Request和Session将实例的作用域限制在HTTP请求/会话期间。GlobalSession作用域基本不使用,只适用于特殊的portlet场景。
Spring AOP(面向切面编程)是Spring框架的一个核心功能,它允许将不同但相关的业务逻辑组件解耦,从而提高了应用程序的可维护性和可重用性。
通过使用Spring AOP,我们可以将与业务逻辑无关的各种横向关注点(如日志记录、事务管理、安全性、缓存等)从业务逻辑中分离出来,避免代码重复,并使得代码更加清晰易懂。
在Spring AOP中,切面(Aspect)是对横向关注点的抽象。切面包含了具体的切点(Pointcut)和通知(Advice),其中切点定义了何时织入通知,而通知则定义了何种行为需要执行。
其工作流程具体如下:
定义切入点:我们需要定义一个或多个切入点以便确定哪些方法需要被拦截处理。切入点指定的是方法的名称和任意参数类型;
编写通知(增强):在Spring AOP中,通知(Advice)是应用在切入点之前或者之后执行的一种代码块。Spring AOP支持以下5种通知类型:
创建代理对象:在运行期间,Spring AOP会为目标对象创建一个代理对象。代理对象通过Spring容器返回给客户端;
执行拦截:在调用代理对象的方法时,Spring AOP自动检查方法是否需要拦截(即是否匹配切入点),如果匹配,则执行相应的通知代码块,然后再调用原始的目标方法。
而从原理上来说,Spring AOP是基于动态代理的实现方式来实现切面编程的。针对不同类型的bean,Spring使用JDK动态代理或CGLIB(Code Generation Library)字节码生成技术来创建代理对象。
其中,如果目标对象实现了至少一个接口,则Spring AOP将使用JDK动态代理。基本原理是利用 Java 的反射机制生成目标对象的代理对象,通过调用代理对象之前调用“前置通知”拦截方法,进行切面编程。
如果目标对象没有实现任何接口,则 Spring AOP 将使用CGLIB(Code Generation Library)库来实现代理。基本原理是在内存中构建出目标对象子类的字节码并载入 JVM 中,生成目标对象的代理对象,也通过调用代理对象之前调用“前置通知”拦截方法,同样可以实现切面编程。
Spring AOP 使用 BeanPostProcessor 在应用中动态创建和织入切面。BeanPostProcessor 拦截容器创建的对象,如果该对象匹配被代理的对象,则会根据上面的两种方式其一,来创建一个新的代理对象并返回。通过使用 BeanPostProcessor,AOP 识别它需要拦截的 bean,并且将切面编织到相应的代码中。
因此,在 Spring AOP 中,BeanPostProcessor 扮演着非常重要的角色。它提供了一种机制,使开发人员可以对 Spring IOC 容器创建的每个 bean 进行定制化处理,进而进行 AOP 代理的创建和织入。
图片来源:
Spring Framework 官网
Spring、SpringBoot全家桶技术栈知识点汇总(欢迎收藏)
Spring系列(一)、Spring入门及七大模块
springboot分析-spring IOC原理拆解和spring MVC模块分析
书籍详情可以去某当、某宝、某东各个网站搜索书籍名称查看~
没有自己中意的可以自选噢,自选规则查看下文
🍻 朋友们,千粉福利来啦!
《小山劝学第1期》 👏 👏 👏
赠书说明:图示图书中任选一本或者不限制(¥100内的书籍自主选择,可以是 非软件行业的书噢,但只限一本噢~)
参与方式:关注+点赞+收藏,评论区评论 “勤能补拙,IT之路,共同进步!”(记得不要漏掉噢,否则抽奖无效~)
开奖时间:2023-06-16 12:00:00
开奖名额:3名
通知方式:开奖后我会向中奖用户发起私信并把结果公布在评论区,不弄虚作假哈~