百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Spring 框架介绍和使用(spring框架的使用步骤)

ccwgpt 2024-10-16 08:10 30 浏览 0 评论

本文主要是对 Spring 的一个基本使用,建议阅读时间 5min。

历史的选择

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框架


相关推荐

用Steam启动Epic游戏会更快吗?(epic怎么用steam启动)

Epic商店很香,但也有不少抱怨,其中一条是启动游戏太慢。那么,如果让Steam启动Epic游戏,会不会速度更快?众所周知,Steam可以启动非Steam游戏,方法是在客户端左下方点击“添加游戏”,然...

Docker看这一篇入门就够了(dockerl)

安装DockerLinux:$curl-fsSLhttps://get.docker.com-oget-docker.sh$sudoshget-docker.sh注意:如果安装了旧版...

AYUI 炫丽PC开发UI框架2016年6月15日对外免费开发使用 [1]

2016年6月15日,我AY对外发布AYUI(WPF4.0开发)的UI框架,开发时候,你可以无任何影响的去开发PC电脑上的软件exe程序。AYUI兼容XP操作系统,在Win7/8/8.1/10上都顺利...

别再说C#/C++套壳方案多了!Tauri这“借壳生蛋”你可能没看懂!

浏览器套壳方案,C#和C++有更多,你说的没错,从数量和历史积淀来看,C#和C++确实有不少方式来套壳浏览器,让Web内容在桌面应用里跑起来。但咱们得把这套壳二字掰扯清楚,因为这里面学问可大了!不同的...

OneCode 核心概念解析——Page(页面)

在接触到OneCode最先接触到的就是,Page页面,在低代码引擎中,页面(Page)设计的灵活性是平衡“快速开发”与“复杂需求适配”的关键。以下从架构设计、组件系统、配置能力等维度,解析确...

React是最后的前端框架吗,为什么这么说的?

油管上有一位叫Theo的博主说,React是终极前端框架,为什么这么说呢?让我们来看看其逻辑:这个标题看起来像假的,对吧?React之后明明有无数新框架诞生,凭什么说它是最后一个?我说的“最后一个”不...

面试辅导(二):2025前端面试密码:用3个底层逻辑征服技术官

面试官放下简历,手指在桌上敲了三下:"你上次解决的技术难题,现在回头看有什么不足?"眼前的候选人瞬间僵住——这是上周真实发生在蚂蚁金服终面的场景。2025年的前端战场早已不是框架熟练...

前端新星崛起!Astro框架能否终结React的霸主地位?

引言:当"背着背包的全能选手"遇上"轻装上阵的短跑冠军"如果你是一名前端开发者,2024年的框架之争绝对让你眼花缭乱——一边是React这位"背着全家桶的全能选...

基于函数计算的 BFF 架构(基于函数计算的 bff 架构是什么)

什么是BFFBFF全称是BackendsForFrontends(服务于前端的后端),起源于2015年SamNewman一篇博客文章《Pattern:BackendsFor...

谷歌 Prompt Engineering 白皮书:2025年 AI 提示词工程的 10 个技巧

在AI技术飞速发展的当下,如何更高效地与大语言模型(LLM)沟通,以获取更准确、更有价值的输出,成为了一个备受关注的问题。谷歌最新发布的《PromptEngineering》白皮书,为这一问题提供了...

光的艺术:灯具创意设计(灯光艺术作品展示)

本文转自|艺术与设计微信号|artdesign_org_cn“光”是文明的起源,是思维的开端,同样也是人类睁眼的开始。每个人在出生一刻,便接受了光的照耀和洗礼。远古时候,人们将光奉为神明,用火来...

MoE模型已成新风口,AI基础设施竞速升级

机器之心报道编辑:Panda因为基准测试成绩与实际表现相差较大,近期开源的Llama4系列模型正陷入争议的漩涡之中,但有一点却毫无疑问:MoE(混合专家)定然是未来AI大模型的主流范式之一。...

Meta Spatial SDK重大改进:重塑Horizon OS应用开发格局

由文心大模型生成的文章摘要Meta持续深耕SpatialSDK技术生态,提供开自去年9月正式推出以来,Meta持续深耕其SpatialSDK技术生态,通过一系列重大迭代与功能增强,不断革新H...

&quot;上云&quot;到底是个啥?用&quot;租房&quot;给你讲明白IaaS/PaaS/SaaS的区别

半夜三点被机房报警电话惊醒,顶着黑眼圈排查服务器故障——这是十年前互联网公司运维的日常。而现在,程序员小王正敷着面膜刷剧,因为公司的系统全"搬"到了云上。"部署到云上"...

php宝塔搭建部署thinkphp机械设备响应式企业网站php源码

大家好啊,欢迎来到web测评。本期给大家带来一套php开发的机械设备响应式企业网站php源码,上次是谁要的系统项目啊,帮你找到了,还说不会搭建,让我帮忙录制一期教程,趁着今天有空,简单的录制测试了一下...

取消回复欢迎 发表评论: