导图社区 SpringFramework
SpringFramework技术的介绍,SpringFramework,通常简称为Spring,是一个开源的企业级Java应用程序框架,由Rod Johnson创建,并于2004年首次发布。Spring Framework的主要目标是简化企业级Java开发,提高开发效率和应用程序的可维护性。
编辑于2024-09-11 15:41:04微信小程序开发知识整理,系统地介绍了微信小程序开发的基础知识,帮助开发者更好地理解和掌握小程序开发的要点和流程。
SpringFramework技术的介绍,SpringFramework,通常简称为Spring,是一个开源的企业级Java应用程序框架,由Rod Johnson创建,并于2004年首次发布。Spring Framework的主要目标是简化企业级Java开发,提高开发效率和应用程序的可维护性。
Maven的特性以及使用部署方法,Maven介绍:Maven是一款为Java项目构建管理、依赖管理的工具(软件),使用Maven可以自动化构建、测试、打包和发布项目,大大提高了开发效率和质量。
社区模板帮助中心,点此进入>>
微信小程序开发知识整理,系统地介绍了微信小程序开发的基础知识,帮助开发者更好地理解和掌握小程序开发的要点和流程。
SpringFramework技术的介绍,SpringFramework,通常简称为Spring,是一个开源的企业级Java应用程序框架,由Rod Johnson创建,并于2004年首次发布。Spring Framework的主要目标是简化企业级Java开发,提高开发效率和应用程序的可维护性。
Maven的特性以及使用部署方法,Maven介绍:Maven是一款为Java项目构建管理、依赖管理的工具(软件),使用Maven可以自动化构建、测试、打包和发布项目,大大提高了开发效率和质量。
SpringFramework
一、 技术体系结构
1. 单体架构:一个项目,一个工程,导出为一个war包,在一个Tomcat上运行,也叫all in one。
单一架构项目主要应用技术框架为Spring,SpringMVC,Mybatis
2. 分布式架构:一个项目,拆分成很多个模块,每个模块是一个IDEA中的一个module。每一个工程都是运行在自己的Tomcat上。模块之间可以互相调用。每一个模块内部可以看成是一个单一架构的应用。
分布式架构,项目主要应用技术框架为SpringBoot(SSM),SpringCloud,中间件等
3. 框架概念和理解
从文件架构的角度理解框架,框架=jar包+配置文件
(1) 框架概念
框架是一个集成了基本结构、规范、设计模式、编程语言和程序库等基础组件的软件系统,它可以用来构建更高级别的应用程序。框架的设计和实现旨在解决特定领域中的常见问题,帮助开发人员更高效、更稳定地实现软件开发目标
(2) 框架优点
1||| 提高开发效率:框架提供了许多预先设计好了的组件和工具,能够帮助开发人员快速进行开发。相较于传统手写代码,在框架提供的规范化环境中,开发者可以更快地实现项目的各种要求
2||| 降低开发成本:框架提供标准化的编程语言、数据操作等代码片段,避免了重复开发的问题,降低了开发成本,提供深度优化的系统,降低了维护成本,增强了系统的可靠性
3||| 提高应用程序的稳定性:框架通常经过了很长时间的开发和测试,其中的许多组件、代码片段和设计模式都得到了验证。重复利用这些组件有助于减少bug的出现,从而提供了应用程序的稳定性
4||| 提供标准化的解决方案:框架通常是针对某个特定领域的,通过提供标准化的解决方案,可以为开发人员提供一种共同的语言和思想基础,有助于更好的进行沟通和协作
(3) 框架缺点
1||| 学习成本高:框架通常具有特定的语言和编程范式。对于开发人员来说,需要花费时间学习其背后的架构、模式和逻辑,这对于新手而言可能会耗费较长时间
2||| 可能存在局限性:虽然框架提高了开发效率并可以帮助开发人员解决常见问题,但是在某些情况下,特定的应用需求可能超出框架的范围,从而导致应用程序无法满足要求。开发人员可能需要更多的控制权和自由度,同时需要在框架和应用程序之间进行权衡取舍
3||| 版本变更和兼容性问题:框架的版本发布和迭代通常会导致代码库的大规模变更,进而导致应用程序出现兼容性问题和漏洞。当框架变更时,需要考虑架构是否向下兼容,以及如何进行适当的测试、迁移和升级
4||| 架构风险:框架涉及到很多抽象和概念,如果开发者没有足够的理解和掌握其架构,可能会导致系统出现设计和架构缺陷,从而影响系统的健康性和安全性
二、 SpringFramework介绍
1. Spring和SpringBootFramework概念
(1) 广义的Spring:Spring技术栈(全家桶),广义的Spring泛指以Spring Framework为基础的Spring技术栈。包括Spring Framework、Spring MVC、SpringBoot、Spring Cloud、Spring Data、Spring Security等
(2) 狭义的Spring:Spring Framework(基础框架),Spring Framework是一个开源的应用程序框架,最初是为了解决企业级开发中各种常见问题而创建的。它提供了很多功能。例如:依赖注入(Dependency Injection)、面向切面编程(AOP)、声明式事务管理(TX)等,其主要目标是使企业级应用程序的开发变得更加简单和快速,并且SpringBoot框架广泛被应用于Java企业开发领域
2. SpringFramework主要功能模块
(1) 功能模块
1||| Core Container:核心容器,在Spring环境下使用任何功能都必须基于IOC容器
2||| AOP&Aspects:面向切面编程
3||| TX:声明式事务管理
4||| Spring MVC:提供了面向Web应用程序的集成功能
(2)
3. SpringFramework主要优势
1||| 丰富的生态系统:Spring生态系统非常丰富,支持许多模块和库,如SpringBoot、Spring Security、Spring Cloud等。可以帮助开发人员快速构建高可靠性的企业应用程序
2||| 模块化的设计:框架组件之间的松散耦合和模块坏设计使得Spring Framework具有良好的可重用性、可扩展性和可维护性。开发人员可以轻松的选择自己需要的模块,根据自己的需要进行开发
3||| 简化Java开发:Spring Framework简化了Java开发,提供了各种工具和API,可以降低开发复杂度和学习成本。同时,Spring Framework支持各种应用场景,包括web应用程序、RESTful API、消息传递、批处理等等
4||| 不断创新和发展:Spring Framework开发团队一直在不断创新和发展,保持与最新技术的接轨,为开发人员提供更加先进和优秀的工具和框架
Spring全家桶的其他框架都是以SpringFramework框架为基础制作的
三、 SpringIOC容器
Spring容器通常称为IOC容器
1. 组件和组件管理的概念
(1)
(2) Spring充当组件管理角色(IOC)
(3) Spring能帮助我们
1||| 创建组件对象
2||| 保存组件对象
3||| 自动组装
4||| 管理事务
5||| 整合其他框架
(4) 组件交给Spring管理的优势
1||| 降低了组件间的耦合:Spring IOC容器通过注入依赖机制,将组件之间的依赖关系削弱,减少了程序组件之间的耦合性,使组件更加松散的耦合。
2||| 提高了代码的可重用性和可维护性:将组件的实例化过程、依赖关系的管理等功能交给Spring IOC容器处理,使得组件代码更加模块化、可重用、更易维护。
3||| 方便配置和管理:Spring IOC容器通过XML文件或注释,轻松的对组件进行配置和管理,使组件的切换、替换等操作更加方便和快捷。
4||| 交给Spring 管理的对象(组件),方可享受Spring框架的其他功能(AOP、声明事务管理等)
四、 SpringIoC容器和核心概念
1. 普通和复杂容器
(1) 普通容器:只能用来存储,没有更多功能
1||| 数组
2||| 集合(List、Set)
(2) 复杂容器:除了能够存储,还能对其中的对象进行管理
Servlet容器:能够管理Servlet(Init、service、destory)、Fliter、Listener这样组件的一生,所以它是一个复杂容器
2. SpringIoC容器介绍
SpringIoC容器是一个复杂容器,它们不仅要负责创建组件的对象、存储组件的对象,还要负责调动组件的方法让他们工作,最终在特定情况下销毁组件。
Spring IOC容器,负责实例化、配置和组装bean组件。容器通过读取配置元数据来获取有关要实例化、配置和组装组件的指令。配置元数据以XML、Java注解或Java代码的形式表现。他允许表达组成应用程序的组件以及这些组件之间丰富的相互依赖关系。
3. Spring IOC容器的具体接口和实现类
(1) SpringIoC容器的接口
BeanFactory提供了配置框架和基本功能,而ApplicationContext添加了更多特定于企业的功能,ApplicationContext是BeanFactory的完整超集。
1||| BeanFactory接口提供了一种高级配置机制,能够管理任何类型的对象,它是SpringIoc容器标准化的超接口
2||| ApplicationContext是BeanFactory的子接口。它扩展了如下功能
i. 更容易与Spring的AOP功能集成
ii. 消息资源处理(用于国际化)
iii. 特定于应用程序给予此接口实现,例如Web应用程序的WebApplicationContext
(2) ApplicationContext容器实现类
1||| ClassPathXmlApplicationContext:通过读取类路径下的XML格式的配置文件创建IOC容器对象
2||| FileSystemXmlApplicationContext:通过文件系统路径读取XML格式的配置文件创建IOC容器对象
3||| AnnotationConfigApplicationContext:通过读取Java配置类创建IOC容器对象
4||| WebApplicationContext:专门为Web应用准备,基于Web环境创建IOC容器对象,并将对象引入ServletContext域中
4. SpringIOC容器管理配置方式
(1) XML配置方式:是Spring框架的最早配置方式之一,通过在XML文件中定义Bean及其依赖关系、Bean的作用域等信息,让SpringIOC容器来管理Bean之间的依赖关系。该方式从Spring框架的第一版开始提供支持
(2) 注解方式:从Spring2.5版本开始提供支持,可以通过在Bean类上使用注解来代替XML配置文件中的配置信息。通过在Bean类上加上相应的注解(如@Component,@Service,@Antowirde等),将Bean注册到Spring IOC容器中,这样Spring IOC容器就可以管理这些Bean之间的依赖关系
(3) Java配置类:从Spring3.0版本开始提供支持,通过Java类来定义Bean、Bean之间的依赖关系和配置信息,从而代替XML配置文件的方式。Java配置类是一种使用Java编写配置信息的方式,通过@Configuration、@Bean等注解来实现Bean和依赖关系的配置。
目前主流的开发环境是以配置类+注解方式进行容器管理配置的
5. Spring IoC/DI总结
(1) Ioc(Inversion of Control)控制反转:IoC主要是针对对象的创建和调用控制而言的,也就是说,当应用程序需要使用一个对象时,不再是应用程序直接创建该对象,而是由IoC容器来创建和管理,即控制权由应用程序转移到IoC容器中,也就是”反转“了控制权。这种方式基本上是通过依赖查找的方式来实现的,即IoC容器维护着构成应用程序的对象,并负责创建这些对象
(2) DI(Dependency Injection)依赖注入:组件之间传递依赖关系的过程中,将依赖关系在容器内部进行处理,这样就不必在应用程序代码中硬编码对象之间的依赖关系,实现了对象之间的解耦合。在Spring中,DI是通过XML配置文件或注解的方式实现的。它提供了三种形式的依赖注入:构造函数注入、Setter方法注入、接口注入
五、 IoC实践和应用
1. Spring IoC/DI实现步骤
(1) 编写配置信息(配置文件:XML,注解,配置)
1||| 组件类信息
2||| 组件之间的引用关系
<?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 https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="..." [1] class="..." [2]> <!-- collaborators and configuration for this bean go here --> </bean> <bean id="..." class="..."> <!-- collaborators and configuration for this bean go here --> </bean> <!-- more bean definitions go here --> </beans>
Spring IoC 容器管理一个或多个组件。这些 组件是使用你提供给容器的配置元数据(例如,以 XML `<bean/>` 定义的形式)创建的。 <bean /> 标签 == 组件信息声明 - `id` 属性是标识单个 Bean 定义的字符串。 - `class` 属性定义 Bean 的类型并使用完全限定的类名。
(2) 实例化IoC容器对象(需要指定配置信息)
提供给 `ApplicationContext` 构造函数的位置路径是资源字符串地址,允许容器从各种外部资源(如本地文件系统、Java `CLASSPATH` 等)加载配置元数据。 我们应该选择一个合适的容器实现类,进行IoC容器的实例化工作: //实例化ioc容器,读取外部配置文件,最终会在容器内进行ioc和di动作 ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "DOS.xml");
(3) 在Java代码中获取组件并使用组件
`ApplicationContext` 是一个高级工厂的接口,能够维护不同 bean 及其依赖项的注册表。通过使用方法 `T getBean(String name, Class<T> requiredType)` ,您可以检索 bean 的实例。允许读取 Bean 定义并访问它们,如以下示例所示: //创建ioc容器对象,指定配置文件,ioc也开始实例组件对象 ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml"); //获取ioc容器的组件对象 PetStoreService service = context.getBean("petStore", PetStoreService.class); //使用组件对象 List<String> userList = service.getUsernameList();
2. 基于XML配置方式的组件管理
(1) 组件(Bean)信息声明配置(Ioc)
Spring Ioc容器管理一个或多个bean。这些Bean是使用用户自己提供给容器的配置元数据创建的(例如,以XML</bean>定义的形式),通过定义XML配置文件,声明组件类信息,交给Spring的Ioc容器进行组件管理。不同的实例化方式对象和组件Ioc的配置方式也不同。
1||| 基于无参构造函数实例化
i.
准备无参构造函数组件
ii.
在已经导入了Spring相关依赖的情况下可以直接创建该文件,该文件默认包含Spring相关的约束
iii.
名称可以任意
iv.
id 为组件的唯一标识方便后期读取 class为组件的类的权限限定符
2||| 基于静态工厂方法实例化
i.
准备静态工厂组件类
ii.
如果是使用静态工厂方法进行实例化需要在<bean/> 标签中指定factory-method属性
3||| 基于实例工厂方法实例化
i.
准备实例工厂组件
ii.
iii.
首先需要配置非静态工厂类的组件信息,然后通过指定非静态工厂对象和方法名,来配置生成的Ioc信息
思路图
(2) 组件(Bean)依赖注入配置(DI)
通过配置文件,实现IOC容器中Bean之间的引用(依赖注入DI配置)。主要涉及注入场景:基于构造函数的依赖注入和基于Setter的依赖注入
1||| 基于构造函数的依赖注入(单个构造参数)
基于构造函数的DI是通过容器调用具有单个或多个参数的构造函数来完成的,每一个参数表示一个依赖项。
i.
准备组件
ii.
新建配置文件,先将组件放入ioc容器中,然后再使用constructor-arg标签将构造参数传值进行di配置
2||| 基于构造函数的依赖注入(多个构造参数)
i.
准备组件
ii.
方案一:按构造参数的顺序进行注入
iii.
方案二:根据构造参数的名称填写值,不需要考虑参数顺序
iv.
方案三:根据构造参数的下角标填写,不用考虑顺序,构造参数的下角标从左到右从0开始。 age=0 name=1 userDao=2
3||| 基于Setter方法依赖注入
准备组件
第一步与多构造参数一致,先加载组件到ioc容器中,然后使用property标签声明属性
思路图
(3) Ioc容器创建和获取
1||| Ioc容器创建
将组件加载到xml文件中,并进行配置形成xml配置文件
2||| Ioc容器获取
根据方案三获取组件时(根据Bean的类型获取),同一个类型,在ioc容器中只能有一个Bean,如果ioc容器中存在多个同类型的bean,会出现异常。ioc的配置一定是实现类,但是可以根据接口类型获取值。(接口加实现类的场景)
(4) 高级特性:组件(Bean)作用域和周期方法配置
1||| 周期方法配置
i. 周期方法:到了对应的时间节点就会主动被调用的方法
我们可以在组件类中定义方法,然后当Ioc容器实例化和销毁组件对象时进行调用。这两个方法我们称为生命周期方法。类似与Servlet的init/destroy方法,我们可以在周期方法完成初始化和释放资源等工作
ii. 周期方法声明
i.
图片中包含初始化方法注释
ii.
周期方法需要在XML文件中声明相应的初始化方法(init-method)和销毁方法(destroy-method),声明之后spring ioc容器就会在对应的时间节点回调对应的方法,我们可以在方法中写好对应的业务即可。初始化方法和销毁方法按照自己的业务需要可只声明其中一个,并不一定需要全部声明!
iii.
2||| 组件作用域配置
i. <bean标签声明Bean,只是将Bean的信息配置给SpringIoc容器。在Ioc容器中,这些<bean标签对应的信息转成Spring内部BeanDefinition对象,BeanDefinition对象内,包含定义的信息(id,class,属性等)。这意味着,BeanDefinition与类概念一样,SpringIOC容器可以根据BeanDefinition对象反射创建多个Bean对象实例。具体创建多少个Bean的实例对象,由Bean的作用域Scope(默认值为单例)指定!
ii. 作用域可选值
I. singleton:在IOC容器中,这个bean的对象始终为单例,它会在IOC容器初始化时创建对象,为默认值
单例模式无论创建多少次都是同一个对象
输出结果
II. prototype:这个bean在IOC容器中有多个实例,它会在获取Bean时创建对象,不是默认值
III. request:请求范围内有效的实例,每次请求时创建对象,不是默认值
IV. session:会话范围内有效的实例,每次会话时创建对象,不是默认值
在WebApplicationContext环境下使用
(5) 高级特性:FactoryBean特性和使用
1||| FactoryBean:是一个SpringIOC容器实例化逻辑的可插拔性点,是一个接口,它用于配置复杂的Bean对象,可以将创建过程存储在FactoryBean的getObject方法中
2||| FactoryBean<T>接口提供三种方法
i. T getObject():返回此工厂创建的对象的实例。该返回值会被存储到IOC容器
ii. boolean isSIngleton():如果此FactoryBean返回单例,则返回true,否则返回false。此方法默认返回true(注意,lombok插件使用,可能影响效果)。
iii. (Java泛型)Class<> getObjectType():返回getObject()方法返回的对象类型,如果事先不知道类型,则返回null。
3||| FactoryBean使用场景
I. 代理类的创建
II. 第三方框架整合
III. 复杂的对象实例化
4||| 使用FactoryBean工厂
I.
准备组件
II.
制作JavaBean的工厂Bean对象
III.
配置完工厂类后在xml文件中只需要指定Bean id和class即可
IV.
5||| BeanFactory和FactoryBean的区别
I. BeanFactory:是IOC中最大的接口,是IOC容器
BeanFactory 是 Spring 框架的基础,其作为一个顶级接口定义了容器的基本行为,例如管理 bean 的生命周期、配置文件的加载和解析、bean 的装配和依赖注入等。BeanFactory 接口提供了访问 bean 的方式,例如 getBean() 方法获取指定的 bean 实例。它可以从不同的来源(例如 Mysql 数据库、XML 文件、Java 配置类等)获取 bean 定义,并将其转换为 bean 实例。同时,BeanFactory 还包含很多子类(例如,ApplicationContext 接口)提供了额外的强大功能。
II. FactoryBean:标准化组件工厂的接口,是组件
FactoryBean 是 Spring 中一种特殊的 bean,可以在 getObject() 工厂方法自定义的逻辑创建Bean!是一种能够生产其他 Bean 的 Bean。FactoryBean 在容器启动时被创建,而在实际使用时则是通过调用 getObject() 方法来得到其所生产的 Bean。因此,FactoryBean 可以自定义任何所需的初始化逻辑,生产出一些定制化的 bean。 一般情况下,整合第三方框架,都是通过定义FactoryBean实现!!!
总的来说,FactoryBean 和 BeanFactory 的区别主要在于前者是用于创建 bean 的接口,它提供了更加灵活的初始化定制功能,而后者是用于管理 bean 的框架基础接口,提供了基本的容器功能和 bean 生命周期管理。
(6) 基于XML方式整合三层架构组件
1||| JdbcTemplate:为了在特定领域帮助我们简化代码,Spring 封装了很多 『Template』形式的模板类。例如:RedisTemplate、RestTemplate 等
测试使用依赖
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>6.0.6</version> </dependency> <!--spring context依赖--> <!--当你引入SpringContext依赖之后,表示将Spring的基础依赖引入了--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>6.0.6</version> </dependency> <!-- 数据库驱动和连接池--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.25</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.8</version> </dependency> <!-- spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>6.0.6</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.3.1</version> </dependency> </dependencies>
1|||
配置JdbcTemplate
2|||
外部配置文件,在xml文件中可以使用<context:property-placeholder location="classpath:" />指定外部文件路径导入外部配置文件,如果有多个配置文件可以使用逗号隔开以实现引入多个外部配置文件的目的
3|||
将JdbcTemplateTest中的构造函数配置到ioc容器中,无参构造函数只需要提供id和class即可,构造函数中的set方法使用<property标签 />指定,由于jdbcTemplate的set方法来自DruidDataSource,在配置property标签时需要指定ref(来源)。
4||| 配置完毕后在JdbcTemplateTest类中新增方法进行数据库操作测试
public void testForIoc() { //1.创建ioc容器并放入xml配置文件 ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring-01.xml"); //2.获取jdbcTemplate组件 JdbcTemplate jdbcTemplate = applicationContext.getBean(JdbcTemplate.class); //3.进行数据库的crud动作 String sql="insert into students (name,gender,age,class) values (?,?,?,?)"; /** * 参数1:String sql可以带占位符 ? * 参数2:传入占位符的值 * 返回值int 影响函数 */ //插入数据 int rows= jdbcTemplate.update(sql,"李强","男",23,"胜威福泉信息化部"); System.out.println("rows:"+rows); //查询单条数据 sql="select * from students where id= ? ;"; /** * 参数1:sql语句 可以使用占位符 ? * 参数2:RowMapper 列名和属性名的映射器接口 * 参数3:可变参数 占位符的值 * 返回值RowMapper指定的对象 * 匿名内部类可以使用lambda表达式简化代码 * lambda表达式,我们可以把它看成是一种闭包,它允许把函数当做参数来使用,是面向函数式编程的思想,一定程度上可以使代码看起来更加简洁 */ Student student1 = jdbcTemplate.queryForObject(sql, (rs, rowNum) -> { //rs 代表结果集 rowNum行数 rs结果集中获取列的值赋值给实体类对象 Student student = new Student(); student.setId(rs.getInt("id")); student.setName(rs.getString("name")); student.setAge(rs.getInt("age")); student.setGender(rs.getString("gender")); student.setClasses(rs.getString("class")); return student; }, 1); System.out.println(student1); //查询所有学生 //BeanPropertyRowMapper能够帮助我们自动映射列和属性值!要求列名和属性名一致,如果不一致需要起别名。该对象不用提供泛型但需要提供返回类 sql="select id,name,gender,age,class as classes from students ;"; List<Student> studentsList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Student.class)); System.out.println(studentsList); }
2|||
(1)
配置接口和Dao层方法
(2)
配置Service层接口和方法
(3)
配置Controller层接口和方法
(4)
配置.properties外部文件
(5)
使用xml文件维护三层之间的关系