Java——Spring框架全面解析

发布于:2025-07-26 ⋅ 阅读:(13) ⋅ 点赞:(0)

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和事务管理,提高代码的可维护性和扩展性。


网站公告

今日签到

点亮在社区的每一天
去签到