Spring框架基础知识

Spring 概述

Spring 使创建 Java 企业应用程序变得容易。它提供了在企业环境中使用 Java 语言所需的一切,支持 Groovy 和 Kotlin 作为 JVM 上的替代语言,并且可以根据应用程序的需要灵活地创建多种架构。从 Spring Framework 5.1 开始,Spring 需要 JDK 8+(Java SE 8+)并为 JDK 11 LTS 提供开箱即用的支持。建议将 Java SE 8 update 60 作为 Java 8 的最低补丁版本,但通常建议使用最新的补丁版本。

Spring 支持广泛的应用场景。在大型企业中,应用程序往往存在很长时间,并且必须运行在升级周期不受开发人员控制的JDK和应用程序服务器上。其他可能作为嵌入服务器的单个 jar 运行,可能在云环境中。还有一些可能是不需要服务器的独立应用程序(例如批处理或集成工作负载)。

Spring 是开源的。它拥有一个庞大而活跃的社区,可根据各种实际用例提供持续的反馈。这帮助 Spring 在很长一段时间内成功发展。

Spring 框架分为多个模块。应用程序可以选择他们需要的模块。核心是核心容器的模块,包括配置模型和依赖注入机制。除此之外,Spring Framework 为不同的应用程序架构提供基础支持,包括消息传递、事务数据和持久性以及 Web。它还包括基于 Servlet 的 Spring MVC Web 框架,以及并行的 Spring WebFlux 反应式 Web 框架。

Spring 的历史和 Spring 框架

随着时间的推移,Java EE 在应用程序开发中的作用不断发展。在 Java EE 和 Spring 的早期,创建应用程序是为了部署到应用程序服务器。今天,在 Spring Boot 的帮助下,应用程序以一种 DevOps 和云友好的方式创建,嵌入了 Servlet 容器,更改起来很简单。从 Spring Framework 5 开始,WebFlux 应用程序甚至不直接使用 Servlet API,并且可以在不是 Servlet 容器的服务器(例如 Netty)上运行。

Spring 不断创新和发展。除了 Spring 框架之外,还有其他项目,例如 Spring Boot、Spring Security、Spring Data、Spring Cloud、Spring Batch 等。重要的是要记住,每个项目都有自己的源代码存储库、问题跟踪器和发布节奏。有关Spring 项目的完整列表,请参阅spring.io/projects

        

设计理念

  • 提供各个级别的选择。Spring 允许您尽可能晚地推迟设计决策。例如,您可以在不更改代码的情况下通过配置切换持久性提供程序。许多其他基础设施问题和与第三方 API 的集成也是如此。

  • 包容不同的观点。Spring 拥抱灵活性,并且对事情应该如何做没有固执己见。它以不同的视角支持广泛的应用需求。

  • 保持强大的向后兼容性。Spring 的演变经过精心管理,以强制在版本之间进行很少的重大更改。Spring 支持精心挑选的一系列 JDK 版本和第三方库,以方便维护依赖 Spring 的应用程序和库。

  • 关心 API 设计。Spring 团队投入了大量的思想和时间来制作直观的 API,这些 API 可以跨越多个版本和多年。

  • 为代码质量设定高标准。Spring Framework 非常强调有意义、最新和准确的 javadoc。它是极少数可以声称代码结构清晰且包之间没有循环依赖关系的项目之一。

2 优点
Spring 是一个开源免费的框架 , 容器 .
Spring 是一个轻量级的框架 , 非侵入式的 .
控制反转 IoC , 面向切面 Aop
对事物的支持 , 对框架的支持
一句话概括: Spring 是一个轻量级的控制反转 (IoC) 和面向切面 (AOP) 的容器(框架)

组成

Spring 框架是一个分层架构,由 7 个定义良好的模块组成。 Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式

组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模
块的功能如下:
核心容器 :核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory ,它
是工厂模式的实现。 BeanFactory 使用 控制反转 IOC ) 模式将应用程序的配置和依赖性规范
与实际的应用程序代码分开。
Spring 上下文 Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。 Spring 上下文
包括企业服务,例如 JNDI EJB 、电子邮件、国际化、校验和调度功能。
Spring AOP :通过配置管理特性, Spring AOP 模块直接将面向切面的编程功能 , 集成到了 Spring
框架中。所以,可以很容易地使 Spring 框架管理任何支持 AOP 的对象。 Spring AOP 模块为基于
Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP ,不用依赖组件,就可以
将声明性事务管理集成到应用程序中。
Spring DAO JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不
同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异
常代码数量(例如打开和关闭连接)。 Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次
结构。
Spring ORM Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包
JDO Hibernate iBatis SQL Map 。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结
构。
Spring Web 模块 Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提
供了上下文。所以, Spring 框架支持与 Jakarta Struts 的集成。 Web 模块还简化了处理多部分请
求以及将请求参数绑定到域对象的工作。
Spring MVC 框架 MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,
MVC 框架变成为高度可配置的, MVC 容纳了大量视图技术,其中包括 JSP Velocity Tiles iText
POI

IoC 基础
IoC 也称为依赖注入 (DI)。这是一个过程,其中对象仅通过构造函数参数、工厂方法的参数或在对象实例被构造或从工厂方法返回后在对象实例上设置的属性来定义它们的依赖项(即,它们使用的其他对象) . 然后容器在创建 bean 时注入这些依赖项。这个过程基本上是 bean 本身的逆过程(因此得名,控制反转),通过使用类的直接构造或诸如服务定位器模式之类的机制来控制其依赖项的实例化或位置。
控制反转 IoC(Inversion of Control) ,是一种设计思想, DI( 依赖注入 ) 是实现 IoC 的一种方法 ,也有人认为DI 只是 IoC 的另一种说法。没有 IoC 的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。
Spring 容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc 容器中取出需要的对象。

导入 Jar
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.10.RELEASE</version>
</dependency>

编写我们的 spring 文件 , 这里我们命名为applicationcontext.xml
<?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="..." class="...">
<!-- 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>


id属性是一个字符串,用于标识单个 bean 定义。

class属性定义 bean 的类型并使用完全限定的类名。

实例化一个容器

 @Test
    public void test1(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationcontext.xml");
        // 取出
        User user = (User) applicationContext.getBean("user");
        System.out.println(user);

    }

IOC 创建对象方式
. 通过无参构造方法来创建
结果可以发现,在调用 show 方法之前, User 对象已经通过无参构造初始化了!
. 通过有参构造方法来创建
. beans.xml 有三种方式编写
<!-- index 指构造方法 , 下标从 0 开始 -->
<constructor-arg index = "0" value = "kuangshen2" />
<!-- name 指参数名 -->
<constructor-arg name = "name" value = "kuangshen2" />
<!-- 第三种根据参数类型设置 -->
<constructor-arg type = "java.lang.String" value = "kuangshen2" />
Bean 的配置
<!--bean就是java对象,由Spring创建和管理-->
<!--
id 是bean的标识符,要唯一,如果没有配置id,name就是默认标识符
如果配置id,又配置了name,那么name是别名
name可以设置多个别名,可以用逗号,分号,空格隔开
如果不配置id和name,可以根据applicationContext.getBean(.class)获取对象;
class是bean的全限定名=包名+类名
-->
<bean id="hello" name="hello2 h2,h3;h4" class="com.kuang.pojo.Hello">
<property name="name" value="Spring"/>
</bean>

import
团队的合作通过 import 来实现 .
<import resource = "{path}/beans.xml" />
依赖注入( DI
依赖注入( Dependency Injection,DI )。
依赖 : Bean 对象的创建依赖于容器 . Bean 对象的依赖资源 .
注入 : Bean 对象所依赖的资源 , 由容器来设置和装配 .
构造器注入
set 注入 ( 重点 )
要求被注入的属性 , 必须有 set 方法 , set 方法的方法名由 set + 属性首字母大写 , 如果属性是 boolean 类型 , 没有 set 方法 , is .
常量注入
<property name = "name" value = " 小明 " />
Bean 注入
<bean id="addr" class="com.kuang.pojo.Address">
<property name="address" value="重庆"/>
</bean>
<bean id="student" class="com.kuang.pojo.Student">
<property name="name" value="小明"/>
<property name="address" ref="addr"/>
</bean>

数组注入
<bean id="student" class="com.kuang.pojo.Student">
<property name="name" value="小明"/>
<property name="address" ref="addr"/>
<property name="books">
<array>
<value>西游记</value>
<value>红楼梦</value>
<value>水浒传</value>
</array>
</property>
</bean>

List 注入
<property name="hobbys">
<list>
<value>听歌</value>
<value>看电影</value>
<value>爬山</value>
</list>
</property>

Map 注入

<property name="card">
<map>
<entry key="中国邮政" value="456456456465456"/>
<entry key="建设" value="1456682255511"/>
</map>
</property>
set 注入

<property name="games">
<set>
<value>LOL</value>
<value>BOB</value>
<value>COC</value>
</set>
</property>
P 命名空间注入 : 需要在头文件中假如约束文件
导入约束 : xmlns:p="http://www.springframework.org/schema/p"
<!--P(属性: properties)命名空间 , 属性依然要设置set方法-->
<bean id="user" class="com.kuang.pojo.User" p:name="狂神" p:age="18"/>

c 命名空间注入 : 需要在头文件中假如约束文件
导入约束 : xmlns:c="http://www.springframework.org/schema/c"
<!--C(构造: Constructor)命名空间 , 属性依然要设置set方法-->
<bean id="user" class="com.kuang.pojo.User" c:name="狂神" c:age="18"/>

Bean 的作用域
Spring 中,那些组成应用程序的主体及由 Spring IoC 容器所管理的对象,被称之为 bean 。简单地讲, bean就是由 IoC 容器初始化、装配及管理的对象 .

Bean 的自动装配
自动装配是使用 spring 满足 bean 依赖的一种方法
spring 会在应用上下文中为某个 bean 寻找其依赖的 bean
Spring bean 有三种装配机制,分别是:
1. xml 中显式配置;
2. java 中显式配置;
3. 隐式的 bean 发现机制和自动装配。
Spring 的自动装配需要从两个角度来实现,或者说是两个操作:
1. 组件扫描 (component scanning) spring 会自动发现应用上下文中所创建的 bean
2. 自动装配 (autowiring) spring 自动满足 bean 之间的依赖,也就是我们说的 IoC/DI
组件扫描和自动装配组合发挥巨大威力,使的显示的配置降低到最少。
 
byName
 
autowire byName ( 按名称自动装配 )
由于在手动配置 xml 过程中,常常发生字母缺漏和大小写等错误,而无法对其进行检查,使得开发效率降低。
采用自动装配将避免这些错误,并且使配置简单化。

<bean id="user" class="com.kuang.pojo.User" autowire="byName">
<property name="str" value="qinjiang"/>
</bean>
当一个 bean 节点带有 autowire byName 的属性时。
1. 将查找其类中所有的 set 方法名,例如 setCat ,获得将 set 去掉并且首字母小写的字符串,即 cat
2. spring 容器中寻找是否有此字符串名称 id 的对象。
3. 如果有,就取出注入;如果没有,就报空指针异常。
byType
autowire byType ( 按类型自动装配 )
使用 autowire byType 首先需要保证:同一类型的对象,在 spring 容器中唯一。如果不唯一,会报不唯一的异常。
使用注解
jdk1.5 开始支持注解, spring2.5 开始全面支持注解。
准备工作: 利用注解的方式注入属性。
1. spring 配置文件中引入 context 文件头
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd

开启属性注解支持!
<context:annotation-config/>

@Autowired (重点)
@Autowired 是按类型自动转配的,不支持 id 匹配。
需要导入 spring-aop 的包!
自动把一个类装配到另外一个类中
@Qualififier
@Autowired 是根据类型自动装配的,加上 @Qualififier 则可以根据 byName 的方式自动装配
@Qualififier 不能单独使用。
 


@Autowired
@Qualifier(value = "cat2")
private Cat cat;
@Autowired
@Qualifier(value = "dog2")
private Dog dog;
@Resource
@Resource 如有指定的 name 属性,先按该属性进行 byName 方式查找装配;
其次再进行默认的 byName 方式进行装配;
如果以上都不成功,则按 byType 的方式自动装配。
都不成功,则报异常。
小结
@Autowired @Resource 异同:
1. @Autowired @Resource 都可以用来装配 bean 。都可以写在字段上,或写在 setter 方法上。
2. @Autowired 默认按类型装配(属于 spring 规范),默认情况下必须要求依赖对象必须存在,如果要允许null 值,可以设置它的 required 属性为 false ,如: @Autowired(required=false) ,如果我
们想使用名称装配可以结合 @Qualififier 注解进行使用
3. @Resource (属于 J2EE 复返),默认按照名称进行装配,名称可以通过 name 属性进行指定。如果没有指定name 属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在
setter 方法上默认取属性名进行装配。 当找不到与名称匹配的 bean 时才按照类型进行装配。但是
需要注意的是,如果 name 属性一旦指定,就只会按照名称进行装配。
它们的作用相同都是用注解方式注入对象,但执行顺序不同。 @Autowired byType @Resource 先 byName
使用注解开发
、说明
spring4 之后,想要使用注解形式,必须得要引入 aop 的包
<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>5.3.5</version>
    </dependency>

Bean 的实现
我们之前都是使用 bean 的标签进行 bean 注入,但是实际开发中,我们一般都会使用注解!
. 配置扫描哪些包下的注解
<!--指定注解扫描包-->
<context:component-scan base-package="com.kuang.pojo"/>

@Component("user")
// 相当于配置文件中 <bean id="user" class="当前注解的类"/>
public class User {
public String name = "111";
}

属性注入
使用注解注入属性
1. 可以不用提供 set 方法,直接在直接名上添加 @value(" ")
@Component("user")
// 相当于配置文件中 <bean id="user" class="当前注解的类"/>
public class User {
@Value("111")
// 相当于配置文件中 <property name="name" value="111"/>
public String name;
}

如果提供了 set 方法,在 set 方法上添加 @value(" ");
衍生注解
我们这些注解,就是替代了在配置文件当中配置步骤而已!更加的方便快捷!
@Component 三个衍生注解
为了更好的进行分层, Spring 可以使用其它三个注解,功能一样,目前使用哪一个功能都一样。
@Controller web
@Service service
@Repository dao
写上这些注解,就相当于将这个类交给 Spring 管理装配了!
小结
XML 与注解比较
XML 可以适用任何场景 ,结构清晰,维护方便
注解不是自己提供的类使用不了,开发简单方便
xml 与注解整合开发 :推荐最佳实践
xml 管理 Bean
注解完成属性注入
使用过程中, 可以不用扫描,扫描是为了类上的注解
<context:annotation-config/>
作用:
进行注解驱动注册,从而使注解生效
用于激活那些已经在 spring 容器里注册过的 bean 上面的注解,也就是显示的向 Spring 注册
如果不扫描包,就需要手动配置 bean
如果不加注解驱动,则注入的值为 null
什么是 AOP
AOP Aspect Oriented Programming )意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP OOP 的延续,是软件开发中的一个热点,也是 Spring 框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
Aop Spring 中的作用
提供声明式事务;允许用户自定义切面
横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要
关注的部分,就是横切关注点。如日志 , 安全 , 缓存 , 事务等等 ....
切面( ASPECT ):横切关注点 被模块化 的特殊对象。即,它是一个类。
通知( Advice ):切面必须要完成的工作。即,它是类中的一个方法。
目标(
Target ):被通知对象。
代理( Proxy ):向目标对象应用通知之后创建的对象。
切入点( PointCut ):切面通知 执行的 地点 的定义。
连接点( JointPoint ):与切入点匹配的执行点。
SpringAOP 中,通过 Advice 定义横切逻辑, Spring 中支持 5 种类型的 Advice:

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值