当前位置: 首页 > news >正文

Java——Spring框架全面解析

Spring框架作为Java开发的主流框架,以其IOC(控制反转)和AOP(面向切面编程)为核心思想,极大简化了企业级应用开发。本文将系统讲解Spring的核心概念及实战用法,包括IOC容器、依赖注入、AOP、事务管理和定时任务等,并对示例代码进行通用化处理,方便开发者直接参考使用。

一、Spring框架简介

1.1 什么是Spring

Spring是一个开源框架,旨在简化企业级应用开发。它以IOC(控制反转)AOP(面向切面编程) 为思想内核,提供了从控制层到数据层的完整解决方案,并支持整合众多第三方框架(如MyBatis、Hibernate等)。

Spring的优势在于:

  • 简化代码,降低耦合度
  • 提供事务管理、日志等通用功能
  • 支持模块化开发,按需选择组件
  • 良好的兼容性和扩展性

1.2 Spring 6版本特性

Spring 6是一次跨越式升级,主要变化包括:

  • 最低支持JDK 17及以上版本
  • javax命名空间迁移到jakarta
  • 兼容Jakarta EE 9/10
  • 支持AOT( Ahead-of-Time)编译技术

二、IOC容器:控制反转思想

2.1 IOC核心思想

IOC(Inversion of Control)即控制反转,指将对象的创建权交给框架,而非由开发者手动创建。这一思想解决了传统开发中对象管理混乱、耦合度高的问题。

传统方式vs IOC方式

  • 传统方式:调用者主动创建依赖对象(如new UserDaoImpl()
  • IOC方式:框架根据配置自动创建并管理对象,开发者只需从容器中获取

2.2 Spring容器类型

Spring提供了多种容器实现,核心接口为BeanFactoryApplicationContext

容器类型特点
BeanFactory顶层接口,提供基本的Bean管理功能
ApplicationContext继承BeanFactory,增加国际化、事件传播等功能,是开发的首选
ClassPathXmlApplicationContext从类路径加载XML配置文件
FileSystemXmlApplicationContext从磁盘路径加载XML配置文件
AnnotationConfigApplicationContext基于注解配置的容器,无需XML

示例:创建ApplicationContext容器

// 从类路径加载XML配置
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");// 从注解配置类加载
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);

三、依赖注入(DI)详解

依赖注入(Dependency Injection)是IOC思想的具体实现,指框架自动为对象的属性赋值,无需手动set或构造方法初始化。

3.1 注入方式

(1)Setter注入

通过setter方法注入属性,XML配置如下:

<bean id="userService" class="com.example.service.UserService"><!-- name:属性名,ref:引用的Bean ID --><property name="userDao" ref="userDao"/>
</bean><bean id="userDao" class="com.example.dao.UserDaoImpl"/>

对应的Service类需提供setter方法:

public class UserService {private UserDao userDao;// 必须提供setter方法public void setUserDao(UserDao userDao) {this.userDao = userDao;}
}
(2)构造方法注入

通过构造方法注入属性,XML配置如下:

<bean id="userService" class="com.example.service.UserService"><constructor-arg name="userDao" ref="userDao"/>
</bean>

对应的Service类需包含带参构造:

public class UserService {private UserDao userDao;// 带参构造方法public UserService(UserDao userDao) {this.userDao = userDao;}
}
(3)自动注入

通过autowire属性自动匹配注入,无需手动指定依赖:

<!-- byName:按属性名匹配Bean ID;byType:按类型匹配 -->
<bean id="userService" class="com.example.service.UserService" autowire="byType"/>

3.2 注入不同类型属性

Spring支持注入多种类型的属性,包括基本类型、集合、对象等:

<bean id="student" class="com.example.domain.Student"><!-- 基本类型 --><property name="id" value="1"/><property name="name" value="张三"/><!-- List集合 --><property name="hobbies"><list><value>读书</value><value>运动</value></list></property><!-- Map集合 --><property name="scores"><map><entry key="数学" value="90"/><entry key="英语" value="85"/></map></property><!-- 引用对象 --><property name="address" ref="address"/>
</bean><bean id="address" class="com.example.domain.Address"><property name="city" value="北京"/>
</bean>

四、基于注解的配置

注解配置可替代XML,简化开发流程,常用注解如下:

4.1 组件扫描

通过@ComponentScan指定扫描包路径,自动注册标注了@Component及其衍生注解的类:

@Configuration
@ComponentScan("com.example") // 扫描com.example包下的所有组件
public class SpringConfig {
}

4.2 常用组件注解

注解作用适用场景
@Component标识组件,放入Spring容器通用组件
@Service标识服务层组件Service类
@Repository标识数据访问层组件Dao接口实现类
@Controller标识控制层组件Controller类
@Scope指定Bean的作用域单例/多例控制

示例:Service层组件

@Service // 标识为服务层组件
@Scope("singleton") // 单例模式(默认)
public class UserService {// 业务逻辑...
}

4.3 依赖注入注解

  • @Autowired:按类型自动注入
  • @Qualifier:配合@Autowired按名称注入
  • @Value:注入基本类型和字符串
@Service
public class UserService {// 按类型注入Dao@Autowired@Qualifier("userDaoImpl") // 指定Bean名称(当存在多个实现类时)private UserDao userDao;// 注入配置文件中的属性@Value("${app.name}")private String appName;
}

五、AOP(面向切面编程)

AOP(Aspect Oriented Programming)是Spring的另一核心思想,用于在不修改源码的情况下增强方法功能(如日志、权限校验等)。

5.1 AOP核心术语

  • 连接点(Joinpoint):可被增强的方法(Spring中仅支持方法)
  • 切点(Pointcut):需要增强的具体方法(通过表达式指定)
  • 通知(Advice):增强的逻辑(如前置通知、后置通知等)
  • 切面(Aspect):切点 + 通知的组合
  • 织入(Weaving):将通知应用到切点的过程

5.2 通知类型

Spring AOP支持5种通知类型:

通知类型作用
前置通知方法执行前执行
后置通知方法正常执行后执行
异常通知方法抛出异常时执行
最终通知无论是否异常,方法执行后必执行
环绕通知方法执行前后均可增强

5.3 AOP实战示例

(1)基于注解的AOP配置
// 1. 定义切面类
@Aspect // 标识为切面
@Component
public class LogAspect {// 2. 定义切点(匹配com.example.service包下的所有方法)@Pointcut("execution(* com.example.service.*.*(..))")public void servicePointcut() {}// 3. 定义通知@Before("servicePointcut()") // 前置通知public void beforeAdvice(JoinPoint joinPoint) {String methodName = joinPoint.getSignature().getName();System.out.println("方法" + methodName + "开始执行...");}@AfterReturning("servicePointcut()") // 后置通知public void afterReturningAdvice() {System.out.println("方法执行成功");}
}// 4. 开启AOP支持(在配置类中)
@Configuration
@ComponentScan("com.example")
@EnableAspectJAutoProxy // 开启AOP注解支持
public class SpringConfig {
}
(2)切点表达式

切点表达式用于精确匹配需要增强的方法,语法如下:

execution(访问修饰符 返回值 包名.类名.方法名(参数列表))

常用通配符:

  • *:匹配任意字符(如任意返回值、任意方法名)
  • ..:匹配任意层级的包或任意个数的参数

示例:

// 匹配com.example.service包下所有类的public方法
execution(public * com.example.service.*.*(..))// 匹配com.example.dao包及其子包中所有类的save开头的方法
execution(* com.example.dao..* .save*(..))

六、事务管理

事务管理是企业级应用的核心需求,Spring提供了声明式事务管理,基于AOP实现,无需手动编写事务代码。

6.1 事务的ACID特性

  • 原子性(Atomicity):事务是不可分割的单位
  • 一致性(Consistency):事务前后数据状态一致
  • 隔离性(Isolation):并发事务互不干扰
  • 持久性(Durability):事务提交后数据永久生效

6.2 声明式事务配置

(1)XML配置方式
<!-- 1. 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/>
</bean><!-- 2. 配置事务属性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><!-- 所有方法使用默认事务配置 --><tx:method name="*" propagation="REQUIRED" isolation="DEFAULT"/><!-- 查询方法设置为只读 --><tx:method name="get*" read-only="true"/></tx:attributes>
</tx:advice><!-- 3. 配置切面(将事务应用到Service层) -->
<aop:config><aop:pointcut id="servicePointcut" expression="execution(* com.example.service.*.*(..))"/><aop:advisor advice-ref="txAdvice" pointcut-ref="servicePointcut"/>
</aop:config>
(2)注解配置方式
// 1. 开启事务注解支持
@Configuration
@EnableTransactionManagement
public class SpringConfig {// 配置事务管理器...
}// 2. 在Service类或方法上添加事务注解
@Service
@Transactional // 类级别事务配置
public class OrderService {// 方法级别事务(覆盖类配置)@Transactional(propagation = Propagation.REQUIRED)public void createOrder() {// 业务逻辑...}
}

6.3 事务传播行为

事务传播行为定义了多事务方法间的调用规则,常用类型:

  • REQUIRED:默认值,若当前有事务则加入,否则新建
  • REQUIRES_NEW:无论当前是否有事务,均新建事务
  • SUPPORTS:支持当前事务,若无则以非事务方式执行
  • MANDATORY:必须在事务中执行,否则抛异常

七、Spring Task定时任务

Spring Task是轻量级的定时任务框架,可替代Quartz实现定时调度功能。

7.1 定时任务配置

(1)XML配置方式
<!-- 1. 扫描组件 -->
<context:component-scan base-package="com.example.task"/><!-- 2. 配置定时任务 -->
<task:scheduled-tasks><!-- 每5秒执行一次 --><task:scheduled ref="myTask" method="execute" cron="0/5 * * * * ?"/>
</task:scheduled-tasks><!-- 任务类 -->
@Component
public class MyTask {public void execute() {System.out.println("定时任务执行:" + new Date());}
}
(2)注解配置方式
// 1. 开启定时任务支持
@Configuration
@ComponentScan("com.example.task")
@EnableScheduling
public class TaskConfig {
}// 2. 定义定时任务
@Component
public class MyTask {// 每5秒执行一次@Scheduled(cron = "0/5 * * * * ?")public void execute() {System.out.println("定时任务执行:" + new Date());}
}

7.2 Cron表达式

Cron表达式用于定义定时规则,格式为:秒 分 时 日 月 周 [年],常用通配符:

  • *:匹配任意值
  • ?:不指定值(用于日和周)
  • /:递增触发(如0/5表示每5秒)
  • -:范围(如10-12表示10到12点)
  • ,:枚举(如MON,FRI表示周一和周五)

示例:

  • 0 0 8 * * ?:每天8点执行
  • 0 0/30 9-18 * * ?:9点到18点每30分钟执行
  • 0 0 12 ? * SAT:每周六12点执行

八、总结

本文涵盖了Spring框架的核心知识点,从IOC容器到定时任务,通过通用化的代码示例展示了Spring的实战用法。Spring的优势在于其松耦合的设计理念,通过IOC和AOP大幅简化了开发流程,同时提供了丰富的企业级特性(如事务管理、定时任务等)。

在实际开发中,建议根据项目需求选择XML或注解配置,合理运用AOP和事务管理,提高代码的可维护性和扩展性。

http://www.xdnf.cn/news/1185517.html

相关文章:

  • Seaborn可视化
  • 如何理解SpringBoot starters的自动装配
  • 【linux】Haproxy七层代理
  • 基于新型群智能优化算法的BP神经网络初始权值与偏置优化
  • docker-compose up -d 显示no configuration file provided: not found什么问题
  • 【C++】二叉搜索数
  • CIU32L051 DMA+Lwrb环形队列实现串口无阻塞性数据的收发 + 数据百分百不丢失的实现
  • Effective C++ 条款01:视 C++ 为一个语言联邦
  • php算法-- 关联数组使用,优化sip账号去重
  • MyBatis高级应用实战指南
  • 构建跨平台远程医疗系统中的视频通路技术方案探究
  • OT82111_VC1:USB OTG音频解码器固件技术解析
  • 华为昇腾NPU卡 文生音频[T2A]大模型suno/bark模型推理使用
  • Java研学-RabbitMQ(三)
  • 杂谈:前端开发中的常见问题
  • XCTF-crypto-幂数加密
  • iOS WebView 调试实战,文件上传与权限弹窗异常的排查路径
  • Oracle MCP本地部署测试
  • 卸油管连接检测误报率↓78%:陌讯多模态融合算法实战解析
  • [Rust 基础课程]猜数字游戏-获取用户输入并打印
  • 在Akamai云平台上为UGC流媒体进行实时转码
  • 百度快排技术分析的核心要素
  • AI小智源码分析——音频部分(一)
  • 【国内电子数据取证厂商龙信科技】谁是躲在“向日葵”后的
  • LE AUDIO CIS/BIS音频传输时延计算方法
  • nacos安装
  • 【57】MFC入门到精通——MFC 多线程编程总结
  • C++ string:准 STL Container
  • 力扣面试150题--寻找旋转排序数组中的最小值
  • C语言指针初步(4)-用void指针模拟qsort函数方法