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

Spring介绍

Spring是企业级应用的核心开发框架,核心理念是:轻量级、分层、解耦合“,目标是简化Java开发

框架概述

Spring是一个 分层的轻量级开源框架,专注于解决对象管理和模块解耦问题。方便与其他框架整合。

设计理念

  • IOC容器:将对象的创建和管理交友框架,而非手动new对象,实现控制反转
  • AOP支持:将日志、事务、权限等 横向管理的功能,与业务逻辑分离,降低耦合。
  • 接口编程:基于接口而非实现编程,提高代码灵活性和可扩展性。
  • 无侵入式:不强制依赖Spring特定类,原有代码可直接接入Spring。

核心模块

Spring框架分为6大核心模块,各个模块可以独立使用。通过依赖关系相互协作。

模块名称核心作用
Spring Core 核心容器提供IOC容器核心实现、负责对象创建、依赖注入、Bean管理
SpringContext上下文扩展Core功能,提供提供环境配置、资源加载、国际化、事件监听等功能
SpringAOP面向切面提供AOP核心实现,支持横切逻辑(如日志、事务)的声明式编程
Spring DAO/.ORM简化数据访问层开发,提供JdbcTemplate封装JDBC,整合Mybatis、Hibernate等框架。
Spring web提供Web开发支持,如SpringMVC架构。servlet继承。
SpringTest整合JUnit、Test NG支持SPring组件的单元测试和集成测试。

Spring 核心概念

1、IOC(Inversion of Control,控制反转)
定义:ioc将对象的创建、依赖注入、生命周期管理交给Spring容器,仅需要 声明需要的对象,不关心怎么创建。— 控制反转

  • 核心实现:DI依赖注入。
    DI是IOC的具体落地方式:Spring容器在创建对象时,自动将其依赖的对象自动注入。
  • IOC容器的两种实现
    • ClassPathXmlApplicationContext:从类路径(resource目录)加载XML配置文件初始化容器。
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserService service = context.getBean(UserService.class);
- AnnotationConfigApplicationContext:从注解配置类中(@Configuration)初始化容器。无XML模式
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
UserService service = context.getBean(UserService.class);

2、AOP(Aspect-Oriented Programming 面向切面编程)
定义:AOP 是一种 “横向编程” 思想:将日志、事务、权限等横跨多个业务模块的 “横切关注点” 抽离为独立的 “切面(Aspect)”,在不修改原有业务代码的前提下,通过 “动态代理” 将切面逻辑植入到业务流程中。

AOP相关术语

术语定义
切面(Aspect)横切关注点的封装(如“日志切面","事务切面”),由切入点和通知组成
通知(Advisor)切面的具体逻辑(如日志的打印前后)
切入点(Pointcut)定义“拿下方法需要被切面需要被拦截
连接点(JoinPoint)所有可能被切面拦截的方法(如所有类的所有方法),切入点时连接点的子集
目标对象被切面拦截的原始业务对象
代理对象Spring为目标对象生成的代理对象,负责执行目标方法+切面逻辑

切面由:切入点和通知组成。 连接点:所有可以被切入的点。切入点:切入切面的点。通知:切面的具体逻辑。目标对象,代理对象。

通知的类型

通知类型执行时机
@Before目标方法执行前执行
@AfterReturning目标方法正常返回后执行(异常时不执行)
@Afterthrowing目标方法抛出异常后执行
@After目标方法执行后执行,无论正常/异常
@Around包裹目标方法,可在方法执行前后自定义逻辑(灵活可控制目标方法是否执行)

AOP实现原理
Spring AOP基于动态代理实现:默认规则

  • 若目标对象实现了接口,使用JDK代理(基于接口实现代理类)。
  • 若目标对象未实现接口:使用CGLIB代理(基于子类生成代理对象,需要引入CGLIB依赖)

案例:日志切面

// 1. 开启AOP支持(在配置类上添加)
@Configuration
@EnableAspectJAutoProxy // 开启AspectJ风格的AOP
@ComponentScan("com.example")
public class SpringConfig {}// 2. 定义日志切面
@Aspect // 标记为切面
@Component // 纳入IoC容器
public class LogAspect {// 切入点:匹配com.example.service包下所有类的所有方法@Pointcut("execution(* com.example.service.*.*(..))")public void servicePointcut() {}// 前置通知:目标方法执行前打印日志@Before("servicePointcut()")public void beforeLog(JoinPoint joinPoint) {String methodName = joinPoint.getSignature().getName(); // 获取方法名System.out.println("前置日志:执行方法 " + methodName);}// 环绕通知:包裹目标方法@Around("servicePointcut()")public Object aroundLog(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("环绕前:开始计时");long start = System.currentTimeMillis();Object result = joinPoint.proceed(); // 执行目标方法long end = System.currentTimeMillis();System.out.println("环绕后:方法耗时 " + (end - start) + "ms");return result;}
}

Spring Bean 详解

Spring IoC 容器管理的对象称为 Bean,Bean 是 Spring 应用的核心组件。以下总结 Bean 的关键特性:

  1. Bean 的生命周期
    Spring Bean 的生命周期从 “创建” 到 “销毁” 分为 7 个核心阶段,开发者可通过接口或配置干预生命周期:

    • 实例化(Instantiation):Spring 调用无参构造创建 Bean 实例。
    • 属性注入(Populate):Spring 自动注入 Bean 的依赖(@Autowired 标注的属性)。
    • 初始化前(Aware 接口回调):若 Bean 实现 BeanNameAware、ApplicationContextAware 等接口,Spring 会回调接口方法(如设置 Bean 名称、上下文)。
    • 初始化(Initialization):
      • 若 Bean 实现 InitializingBean 接口,调用 afterPropertiesSet() 方法。
      • 执行自定义 init-method(XML 配置)或 @PostConstruct 注解方法。
    • 就绪(Ready):Bean 实例化完成,可被容器获取并使用。
    • 销毁前(Destruction):
      • 若 Bean 实现 DisposableBean 接口,调用 destroy() 方法。
      • 执行自定义 destroy-method(XML 配置)或 @PreDestroy 注解方法。
    • 销毁(Destroyed):Bean 从容器中移除,资源释放。
  2. Bean 的作用域
    Bean 的作用域定义了 Bean 实例的 “创建次数” 和 “存活范围”,默认是 singleton(单例)。Spring 提供 6 种作用域:

作用域名称说明适用场景
singleton容器中仅存在1 个 Bean 实例,所有请求共享该实例(默认)。无状态组件(如 Service、Dao)
prototype每次获取 Bean 时新建 1 个实例(容器仅创建,不销毁)。有状态组件(如 Request、Session)
request每个 HTTP 请求创建 1 个实例,请求结束后销毁(仅 Web 环境)。Web request 级别的数据存储
session每个 HTTP Session 创建 1 个实例,Session 过期后销毁(仅 Web 环境)。Web session 级别的数据存储
application整个 Web 应用共享 1 个实例,应用停止后销毁(仅 Web 环境)。应用级全局配置
websocket每个 WebSocket 连接创建 1 个实例(仅 WebSocket 环境)。WebSocket 通信

Bean定义方式
Spring 支持 3 种 Bean 定义方式,推荐优先使用注解或 Java Config

  1. XML 配置(传统方式,适用于老项目):

  2. 注解驱动(主流方式,简化配置):

    • 用 @Component 及其衍生注解标记类为 Bean:
      • @Component:通用组件(无明确分层)。
      • @Service:业务层组件(Service)。
      • @Controller:Web 层组件(Controller)。
      • @Repository:数据访问层组件(Dao)。
  3. Java Config(纯 Java 配置,无 XML):
    通过 @Configuration 标记配置类,@Bean 注解定义 Bean:

    @Configuration
    public class SpringConfig {// 手动定义Bean,返回值为Bean实例,方法名为Bean ID@Beanpublic UserDao userDao() {return new UserDao();}@Beanpublic UserService userService() {UserService service = new UserService();service.setUserDao(userDao()); // 手动注入依赖return service;}
    }
    

spring事务管理

事务是保证数据一致性的核心机制,Spring 提供声明式事务(无侵入)和编程式事务(手动编码),推荐使用声明式事务。

  1. 事务的 ACID 特性
    • 原子性(Atomicity):事务要么全部执行,要么全部回滚(无中间状态)。
    • 一致性(Consistency):事务执行前后数据完整性不变(如转账前后总金额不变)。
    • 隔离性(Isolation):多个事务并发执行时,相互不干扰。
    • 持久性(Durability):事务提交后,数据永久保存到数据库。
  2. 事务核心接口
  3. 事务传播行为
    事务传播行为定义 “多个事务方法嵌套调用时,事务如何传递”,Spring 提供 7 种传播行为,常用 3 种:
传播行为常量说明
REQUIRED(默认)若当前有事务,加入事务;若无事务,新建事务(如 ServiceA 调用 ServiceB,共用一个事务)。
REQUIRES_NEW无论当前是否有事务,都新建一个独立事务(如日志记录,不影响主事务)。
SUPPORTS若当前有事务,加入事务;若无事务,以非事务方式执行(不常用)。
  1. 声明式事务
    通过 @Transactional 注解实现,步骤如下:

    1. 配置事务管理器(以Mybatis为例)
    @Configuration
    @EnableTransactionManagement // 开启声明式事务支持
    public class TxConfig {// 数据源(省略DataSource配置)@Beanpublic DataSource dataSource() { ... }// 事务管理器@Beanpublic PlatformTransactionManager transactionManager(DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}
    }
    
    1. 在业务方法上使用@Transaction:
    @Service
    public class OrderService {@Autowiredprivate OrderDao orderDao;// 声明式事务:默认传播行为REQUIRED,隔离级别DEFAULT@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)public void createOrder(Order order) {orderDao.insertOrder(order); // 插入订单// 若抛出异常,事务自动回滚if (order.getAmount() < 0) {throw new RuntimeException("金额非法");}}
    }
    
  2. @Transactional 不生效的常见场景

    • 方法不是 public 修饰(Spring 事务仅对 public 方法生效)。
    • 事务方法自调用(如 serviceA() 调用本类的 serviceB(),AOP 无法拦截)。
    • 异常被手动捕获(未抛出到事务管理器,无法触发回滚)。
    • 未配置 TransactionManager 或未开启 @EnableTransactionManagement。
    • 注解指定的 rollbackFor 不包含实际抛出的异常(默认仅回滚 RuntimeException)。

SpringWeb

常见问题

  1. Bean 循环依赖如何解决?
    场景:A 依赖 B,B 依赖 A(如 A -> B -> A)。
    Spring 解决方案:使用三级缓存(singletonObjects、earlySingletonObjects、singletonFactories),提前暴露未初始化完成的 Bean 实例,避免循环等待。
    注意:prototype 作用域的 Bean 无法解决循环依赖(Spring 不缓存 prototype Bean)。
  2. AOP 与事务的执行顺序?
    事务是通过 AOP 实现的,多个切面的执行顺序可通过 @Order 注解指定(值越小,优先级越高)。
    若未指定顺序,默认事务切面优先级低于自定义切面(如日志切面先执行,事务切面后执行)。
  3. 如何实现 Spring 容器的启动监听?
    实现 ApplicationListener 接口,重写 onApplicationEvent 方法,容器初始化完成后会自动触发。
http://www.dtcms.com/a/350845.html

相关文章:

  • Linux iptables 防火墙
  • Linux网络编程基础API
  • [灵动微电子六步换向(方波控制)方案MM32BIN560C] 六步换向实现和规律
  • PostgreSQL诊断系列(2/6):锁问题排查全攻略——揪出“阻塞元凶”
  • RK3568 Linux驱动学习——pinctrl和gpio子系统
  • onnx入门教程(四)——ONNX 模型的修改与调试
  • Day24: NumPy 奥德赛:用科学计算的魔法征服数据宇宙!
  • 32.Ansible平台搭建
  • 2024年09月 Python(二级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • NFC线圈设计计算
  • 力扣热题——前K个高频元素
  • 记一次Arrays.asList集合删除的错误
  • Java vs Kotlin 在实际开发中的主要区别与面试题总结
  • 太阳光模拟器在国防军工中的应用
  • k8s-容器化部署论坛和商城服务(小白的“升级打怪”成长之路)
  • K8s Pod驱逐机制详解与实战
  • SpringBoot防重放攻击的5种实现方案
  • 什么是数据库?现代数据库类型、示例与应用(2025)
  • 深入理解 iptables:Linux 防火墙从入门到精通
  • Vue3使用 DAG 图(AntV X6)
  • 2024年12月 Python(二级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • Spring Boot 3.5 新特性
  • C++ namespace
  • 国内外大模型体验与评测:洞察智能时代的核心驱动力一、引言
  • DataX HdfsWriter 插件文档
  • 实现自己的AI视频监控系统-第二章-AI分析模块2
  • Java全栈开发面试实战:从基础到微服务的完整技术解析
  • Oracle数据库如何修改字段中的两个字符
  • CF2133C 下界(The Nether)
  • 敏捷价值实证:亚马逊如何用敏捷破解技术项目的“价值迷雾”?