Spring 框架介绍和使用

news2024/11/19 13:36:59

微信公众号:运维开发故事,作者:老郑

历史的选择

Spring 作为一个基础的框架,是在 Java EE 开发历史中,是成千上万公司选择。单独使用 Spring 的非常少了,很多都是用 Spring-Boot/Spring-Cloud 来开发,但是 Spring 基础依然是我们使用的基石。我们将一起来聊一聊 Spring 的基本使用。首先我们一起来了解一下 Spring 框架整体架构图如下:图片

  1. 数据访问/集成,包括 JDBC 、ORM、OXM、JMS 和 Transaction 模块;

  2. WEB 模块,包括 WebSocket、Servlet、Web、Porlet 模块;

  3. 核心容器,包括 Bean 模块、Core 模块、Context 模块 和 SpEL 模块;

  4. 其他部分,包括:AOP、Test 等模块

Spring 同类框架

  • Micronaut

  • Quarkus

Spring 核心功能

核心功能:控制反转(IOC) 、AOP 非核心功能:事件驱动、国际化、资源管理,数据绑定、类型转换 、SpEL、单元测试等。

PS:核心功能,在本文会有使用实践。

Spring Bean 容器

控制反转(IOC)是 Spring 框架的核心功能之一,其本质的就是将用户创建 Bean 的过程赋予给 IOC 容器去完成,实现 Bean 创建权利的反转为容器来创建 Bean 和依赖 Bean 。

图片

image.png

Bean 创建

Spring 容器创建 Bean 只需要三个步骤:

  1. 定义 Bean

  2. 创建 Bean 容器/Bean 工厂

  3. 获取 Bean 对象

举一个例子:

public class TestMain {

    public static void main(String[] args) {
        ApplicationContext applicationContext =
                new AnnotationConfigApplicationContext(AppConfig.class);
        Student student = applicationContext.getBean(Student.class);
        student.study();
        student.sleep();
        student.study();
    }
}

@Configuration
@Import(Student.class)
class AppConfig {

}

@Component
class Student {

    private String name;

    private Integer source;

    public void study() {
        System.out.println("学习中...");
    }

    public void sleep() {
        System.out.println("休息中...");
    }
    // setter getter
}

运行上面的代码我们可以得到一下结果:

学习中...
休息中...
学习中...

上面的代码执行什么呢?其实我们可以将 ApplicationContext理解为 Spring 容器对象,然后我们在 AppConfig 配置类中去定义 Spring 容器去帮助我们加载那些 Bean ,最后我们通过 getBean 方法获取我们注册的 Bean 对象。如下图:图片在这个过程中使用到那些关键的接口/类呢?

  • BeanFactory� 是 Bean 的抽象工厂,也就是我们 ApplicationContext 的一个父接口。

  • BeanDefinition� 是 Bean 的定义信息, 比如 beanName, className, isAbstract� 等 Bean 定义信息。

注入依赖 (DI)

Spring IOC 容器主要是解决了 Bean 的创建和依赖管理的问题。我们常见的有两种依赖注入方式:

  1. 属性注入

  2. 构造方法注入

属性注入

通过成员属性的方式实现 Bean 的自动注入

@Component
class Student {
    @Autowired
    private Address address;
    // ...
}

@Component
class Address {
    // ...
}

  • 通过 @Component可以将 Student 、Address 类标记为一个 bean 对象

  • 通过 @Autowired可以将依赖 Bean 自动注入进来。

构造方法注入

通过构造方法实现 Bean 的自动注入

@Component
class Student {
    
 public Student(Address address) {
        this.address = address;
    }
}

@Component
class Address {
    // ...
}

Spring 的 IOC 解决了什么问题?

  1. 容器化,Spring包含并管理应用中对象的生命周期和配置(配置成单例还是原型,以及什么时候使用什么时候销毁)。

  2. 方便解耦,简化开发,Spring就是一个大工厂,可以将所有对象创建和依赖关系维护交给Spring管理,实现松耦合。符合高内聚低耦合的思想,这个特性也叫IOC(控制反转)。

  3. AOP编程的支持,Spring提供面向切面的编程,可以方便的实现对程序进行权限拦截、运行监控等功能,是通过动态代理和CGlib实现的,底层原理是反射。

  4. 声明式事务的支持,通过AOP来实现。不需通过编程的方式而进行管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明,便可将事务规则应用到业务逻辑中。

  5. 方便程序的测试,Spring对Junit4的支持,可以通过注解方便的测试Spring程序。

  6. 方便集成各种优秀框架,Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架的直接支持(如Struts2、Hibernate、MyBatis等)。

  7. 异常处理,Spring提供方便的API把具体技术相关的异常转化为一致的unchecked异常(比如由JDBC、Hibernate或者JDO抛出的异常)。SpringMVC也有一个异常集中处理的思想,将异常抛给SpringMVC框架,由框架来处理异常。

  8. 降低JavaEE API的使用难度,Spring对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低。

Spring AOP 面向切面

AOP(Aspect Oriented Programming)是面向切面的意思。

理解 AOP

Java 是一个面向对象(OOP)的编程语言,但是它有一个弊端就是需要为多个不具有继承关系的对象引入一个公共行为时,例如:日志记录、权限验证、事务管理、访问统计等公共行为,这样不便于维护,而且有大量重复代码,AOP 可以实现和 AOP 的互补。

举个例子: 我们有两个逻辑登录业务、订单业务,需要在他们调用前后进行:权限验证、日志记录等公共逻辑。

  1. 通过 OOP 的方式实现我们需要做一个逻辑模板:权限验证,具体逻辑(登录、订单),日志记录。

  2. 通过 AOP 的方式实现我们只需针对具体逻辑(登录、订单)前后做一个自定义切点,进行权限验证、日志记录。

如下图:图片经过 AOP 方式处理过后,我们可以减少公共对象的引用、通过非继承的方式来处理切入逻辑的拦截,实现公共逻辑和业务的逻辑的松耦合关系。

AOP 实现

Spring 通过代理的方式去实现 AOP,Java 代理的两种模式:静态代理、动态代理。

  • 静态代理:静态代理是指在程序运行前,可以理解为是 .java 文件编译后就存在代理类的字节码 .class 文件。

  • 动态代理:动态代理指在程序运行期间通过 JVM 反射等动态机制,在运行期生成代理对象确定代理逻辑。

Spring 的两种代理模式:

  • JDK 代理:核心类 JdkDynamicAopProxy。

  • GCLIB 代理:核心类 ObjenesisCglibAopProxy。

两种代理的选择:如果 Bean 实现了接口就采用 JDK 代理, 如果没有实现就采用 GCLIB 代理。

AOP 使用

假设已经有一个 UserService 类提供了登录业务,我们需要对该业务做一个【权限验证】、【日志记录】这两个公共逻辑,在不修改 UserService 类代码的前提下就可以通过 AOP 来解决。示例如下:

// 1. 测试类
public class AopTest {
    public static void main(String[] args) {
        ApplicationContext applicationContext =
                new AnnotationConfigApplicationContext(AopConfig.class);
        UserService userService = applicationContext.getBean(UserService.class);
        userService.login("admin", "123456");
    }
}

// 2. 配置类
@EnableAspectJAutoProxy
@Configuration
@Import({UserService.class, ValidateAspect.class})
class AopConfig {


}

// 业务类
@Component
class UserService {
    public String login(String username, String password) {
        System.out.println("username:" + username + ",password:" + password);
        return "ok";
    }
}

// Aspect
@Aspect
@Component
class ValidateAspect {

    @Pointcut("execution(public * io.zhengsh.simu.spring.UserService.*(..))")
    public void servicePoint() {
        // Do nothing
    }


    @Around("servicePoint()")
    public Object doAroundService(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("validate param invoke !!!");
        return joinPoint.proceed();
    }
}



maven 依赖

<!-- Spring核心依赖 -->
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
  </dependency>
  <!-- Spring beans包-->
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>${spring.version}</version>
  </dependency>
  <!-- Spring 容器包 -->
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
  </dependency>

  <!-- aop -->
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${spring.version}</version>
  </dependency>

  <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.9.1</version>
  </dependency>

参考文档

  • Spring 官方文档

  • 骆驼整理说-Spring AOP

  • Java-为什么使用Spring框架

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/62762.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文件系统监视器

QFileSystemWatcher类通过监视指定路径的列表来监视文件系统对文件和目录的更改。 构造函数&#xff1a; 常用函数&#xff1a; addPath&#xff08;&#xff09;添加路径addPaths&#xff08;&#xff09;添加多个路径directory&#xff08;&#xff09;返回正在监视的目录的…

【JS】数据结构之队列

文章目录基本概念代码实现基本概念 队列&#xff1a;它是一种运算受限的线性表&#xff0c;FIFO&#xff08;先进先出&#xff09;特性&#xff1a;它只运行表的前端进行删除操作&#xff0c;在表的后端进行添加操作面对无法同时处理多个请求的场景&#xff0c;我们通常就会使…

HTML小游戏16 —— 消除游戏《魔法石》源码(附完整源码)

&#x1f482; 网站推荐:【神级源码资源网】【摸鱼小游戏】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 想寻找共同学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】&#x1f4ac; 免费且实用的计…

计算机组成原理(一)计算机系统概论

目录前言计算机硬件的组成和分类冯.诺依曼结构的基本思想运算器存储器控制器程序和指令控制器的基本任务指令流和数据流适配器与I/O设备输入设备计算机软件的组成与分类计算机系统的层次结构计算机系统的性能指标软硬件逻辑的等价性前言 计算机组成原理这门课可以说是计算机专…

b2b2c o2o 多商家入驻商城 直播带货商城 电子商务

一个好的SpringCloudSpringBoot b2b2c 电子商务平台涉及哪些技术、运营方案&#xff1f;以下是我结合公司的产品做的总结&#xff0c;希望可以帮助到大家&#xff01; 搜索体验小程序&#xff1a;海哇 1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买…

Aqwa 带你掌握船舶与海洋工程水动力理论与工程应用

作者&#xff1a;高巍&#xff0c;仿真秀科普作者 一、写在前面 20世纪60年代欧洲北海发现了储量丰富的油气资源&#xff0c;随着1973年第二次石油危机的到来&#xff0c;欧洲国家能源自主的迫切需要推进了北海油气资源的开发进程&#xff0c;推动了海洋工程技术发展。 为了…

【多线程(三)】生产者和消费者模式

文章目录3.生产者和消费者模式前言3.1生产者和消费者模式概述3.2生产者和消费者案例3.3 阻塞队列基本使用3.4 阻塞队列实现等待唤醒机制总结3.生产者和消费者模式 前言 在线程世界里&#xff0c;生产者就是生产数据的线程&#xff0c;消费者就是消费数据的线程。在多线 程开发…

SQL SERVER数据库修复之REPAIR_ALLOW_DATA_LOSS级别简介和实例

目录 &#xff08;一&#xff09;前言 &#xff08;二&#xff09;关于DBCC CHECKxxx系列命令 1. DBCC CHECKALLOC 2. DBCC CHECKCATALOG 3. DBCC CHECKDB &#xff08;1&#xff09;基本概念 &#xff08;2&#xff09;基本语法 &#xff08;3&#xff09;参数说明 &…

分析常见限流算法及手写三种(计数器、漏斗、令牌桶)代码实现

常见的限流算法分析 限流在我们日常生活中经常见到&#xff0c;如火车站门口的栏杆、一些景点的门票只出售一定的数量 等等。在我们的开发中也用到了这种思想。 为什么要限流 在保证可用的情况下尽可能多增加进入的人数,其余的人在排队等待,或者返回友好提示,保证里面的进行…

机器如何快速学习数据采集

很多人都在思考如何利用机器学习&#xff08;ML&#xff09;算法来提高产品或服务的质量。 如果你正在考虑采用ML&#xff0c;以正确的格式收集正确的数据&#xff0c;将会降低你的数据清理工作以及数据浪费。 要收集所有数据 收集所有数据是非常重要的。除非你真正训练一个…

Excel基于分隔符拆分列

1、示例数据 id name describe 1 张三 学生 2 李四 老师 3 王五 学生 2、将数据复制到Excel中 数据目前都在A列中 3、将数据一次拆分到多个列 Excel基于分隔符拆分列&#xff0c;将数据一次拆分到多个列。 选中数据&#xff0c;数据-分列-分列 设置分隔符 点击完成后&…

【Python自然语言处理】使用逻辑回归(logistic)对电影评论情感分析实战(超详细 附源码)

需要源码和数据集请点赞关注收藏后评论区留言私信~~~ 一、舆情分析 舆情分析很多情况下涉及到用户的情感分析&#xff0c;或者亦称为观点挖掘&#xff0c;是指用自然语言处理技术、文本挖掘以及计算机语言学等方法来正确识别和提取文本素材中的主观信息&#xff0c;通过对带有…

使用Visual Studio Code 进行Python编程(一)

1、下载Visual Studio Code 到微软的Visual Studio Code官方主页下载Visual Studio Code: Visual Studio: 面向软件开发人员和 Teams 的 IDE 和代码编辑器Visual Studio 开发工具和服务让任何开发人员在任何平台和语言的应用开发都更加轻松。 随时随地免费使用代码编辑器或 I…

Spire.Office for .NET 7.12.0 2022年最后版本?

谷歌能找到破解版是破坏强签名&#xff0c;不能用web&#xff0c;请把大家不要用Spire.Office for .NET is a combination of Enterprise-Level Office .NET API offered by E-iceblue. It includes Spire.Doc, Spire.XLS, Spire.Spreadsheet, Spire.Presentation, Spire.PDF, …

数据库开发项目 flask + html 01

目的 开放平台&#xff08;网站&#xff09; 前端开发 HTML CSS JavaScript Web框架&#xff1a; 接受请求并处理 MySQL数据库&#xff1a; 存储数据 快速上手&#xff1a; 基于 Flask Web框架 快速搭建网站。 进阶&#xff1a; 基于 Django框架 1. 快速开发网站 安装框架 …

(附源码)SSM介绍信智能实现系统 毕业设计 260930

SSM介绍信智能实现系统 摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&…

java+mysql基于SSM的大学生兼职信息系统-计算机毕业设计

开发环境 运行环境&#xff1a; 开发工具:IDEA /Eclipse 数据库:MYSQL5.7 应用服务:Tomcat7/Tomcat8 使用框架:SSM(springspringMVCmybatis)vue 项目介绍 论文主要是对大学生兼职信息系统进行了介绍&#xff0c;包括研究的现状&#xff0c;还有涉及的开发背景&#xff0c;然…

分享几款免费实用的国产内网穿透工具

对于没有公网IP的用户来说&#xff0c;如何实现远程管理或让局域网的服务可以被公网访问到是一个问题。当然&#xff0c;也有很多类似的需求&#xff0c;比如&#xff1a; 微信公众号小程序开发调试公网访问本地web项目异地远程处理公司服务问题异地访问公司内网财务/管理系统…

Qt 中模型视图编程的基本概念

背景 一个应用程序本质可以抽象为三部分&#xff1a;界面、逻辑处理、数据。程序中存储有大量的数据&#xff0c;经过逻辑处理后、通过界面展示给用户&#xff0c;同时用户可以通过界面对数据进行编辑&#xff0c;如下图所示&#xff1a; Qt 中的模型视图架构就是用来实现大量…

Spring_第3章_AOP+事务

Spring_第3章_AOP事务 文章目录Spring_第3章_AOP事务一、AOP1 AOP简介问题导入1.1 AOP简介和作用【理解】1.2 AOP中的核心概念【理解】2 AOP入门案例【重点】问题导入2.1 AOP入门案例思路分析2.2 AOP入门案例实现【第一步】导入aop相关坐标【第二步】定义dao接口与实现类【第三…