全网最全Spring APO原理 & Spring MVC原理解析

本文全面解析Spring AOP的原理,包括切面、连接点、通知等核心概念,以及AOP的JDK和Cglib两种代理方式。同时,详细介绍了Spring MVC的流程,从请求到DispatcherServlet,再到Controller、ModelAndView,最后返回响应。文章还预告了后续关于Spring Boot、JPA和Mybatis缓存的内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

全网最全 Spring APO原理 &Spring MVC原理解析

Spring APO 原理

一,Spring APO概念

“横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect”,即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

使用"横切"技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。

AOP主要应用场景有:

  • Authentication 权限
  • Caching 缓存
  • Context passing 内容传递
  • Error handling 错误处理
  • Error handling 错误处理
  • Lazy loading 懒加载
  • Debugging 调试
  • logging, tracing, profiling and monitoring 记录跟踪 优化 校准
  • Performance optimization 性能优化
  • Persistence 持久化
  • Resource pooling 资源池
  • Synchronization 同步
  • Transactions 事务

二, AOP核心概念

1、切面(aspect):类是对物体特征的抽象,切面就是对横切关注点的抽象

2、横切关注点:对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点。

3、连接点(joinpoint):被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器。

4、切入点(pointcut):对连接点进行拦截的定义

5、通知(advice):所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类。

6、目标对象:代理的目标对象

7、织入(weave):将切面应用到目标对象并导致代理对象创建的过程

8

<think>我们注意到用户输入的是“springapo”,这看起来像是拼写错误,用户可能想询问的是SpringAOP(AspectOrientedProgramming,面向切面编程)。因此,我们将按照SpringAOP的相关知识进行回答。回答部分:SpringAOP(面向切面编程)是Spring框架提供的一个模块,用于实现面向切面编程。它允许开发者将横切关注点(如日志记录、事务管理、安全等)与业务逻辑分离,从而提高代码的模块化。SpringAOP通过代理模式实现,主要使用两种代理方式:JDK动态代理(针对接口)和CGLIB代理(针对类)。关键概念:1.切面(Aspect):一个横切多个类的模块。在Spring中,切面由带有@Aspect注解的类实现。2.连接点(JoinPoint):程序执行过程中的一个点,如方法执行或异常处理。在SpringAOP中,连接点总是代表方法执行。3.通知(Advice):切面在特定连接点执行的动作。不同类型的通知包括:-前置通知(Beforeadvice):在连接点之前执行。-后置通知(Afterreturningadvice):在连接点正常完成后执行(例如,方法返回没有抛出异常)。-异常通知(Afterthrowingadvice):在方法抛出异常时执行。-最终通知(After(finally)advice):无论连接点以何种方式退出(正常或异常)都执行。-环绕通知(Aroundadvice):围绕连接点执行,可以在方法调用前后自定义行为,并控制是否执行连接点。4.切点(Pointcut):匹配连接点的表达式。通知与切点表达式关联,并在匹配的连接点上运行。5.引入(Introduction):允许向现有类添加新方法或属性。6.目标对象(TargetObject):被一个或多个切面通知的对象。7.AOP代理(AOPProxy):由AOP框架创建的对象,用于实现切面契约(通知方法执行等)。在Spring中,可以是JDK动态代理或CGLIB代理。实现步骤:1.添加依赖:在项目中添加SpringAOP的依赖(如使用Maven)。2.定义切面:使用@Aspect注解标记一个类。3.定义通知:在切面类中,使用@Before,@After,@Around等注解定义通知方法,并通过切点表达式指定连接点。4.启用AOP:在配置类上使用@EnableAspectJAutoProxy注解来启用自动代理功能。示例代码:首先,添加Maven依赖(假设使用SpringBoot):```xml<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>```定义一个切面类:```javaimportorg.aspectj.lang.annotation.Aspect;importorg.aspectj.lang.annotation.Before;importorg.springframework.stereotype.Component;@Aspect@ComponentpublicclassLoggingAspect{//定义前置通知,在com.example.service包下所有类的所有方法执行前执行@Before("execution(*com.example.service.*.*(..))")publicvoidlogBefore(){System.out.println("方法即将执行...");}}```启用AOP(在SpringBoot主类或配置类上):```javaimportorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.context.annotation.EnableAspectJAutoProxy;@SpringBootApplication@EnableAspectJAutoProxy//启用自动代理,SpringBoot默认会启用,所以可以省略publicclassApplication{publicstaticvoidmain(String[]args){SpringApplication.run(Application.class,args);}}```注意事项:-在SpringAOP中,默认使用JDK动态代理,如果目标对象没有实现接口,则使用CGLIB代理。可以通过@EnableAspectJAutoProxy(proxyTargetClass=true)强制使用CGLIB代理。-SpringAOP只能应用于Spring容器管理的bean。-SpringAOP仅支持方法级别的连接点(不支持字段、构造器等)。解释:通过上述方式,我们可以将日志记录这样的横切关注点从业务代码中分离出来,实现更好的代码组织和维护。相关问题:根据回答内容,提出与SpringAOP相关的四个问题。</think> Spring AOP(Aspect-Oriented Programming)是Spring框架的核心模块,用于实现横切关注点(如日志、事务、安全)的模块化。以下是关键实现原理: ### 一、Spring AOP核心实现 #### 1. 基本依赖 (Maven) ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> ``` #### 2. 定义切面(Aspect) ```java import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; @Aspect @Component public class LoggingAspect { // 定义切点:匹配Service包下所有方法 @Pointcut("execution(* com.example.service.*.*(..))") public void serviceMethods() {} // 前置通知 @Before("serviceMethods()") public void logBefore(JoinPoint joinPoint) { System.out.println("执行方法: " + joinPoint.getSignature().getName()); } // 环绕通知(控制方法执行) @Around("serviceMethods()") public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable { long start = System.currentTimeMillis(); Object result = joinPoint.proceed(); // 执行目标方法 long duration = System.currentTimeMillis() - start; System.out.println("方法执行耗时: " + duration + "ms"); return result; } } ``` #### 3. 启用AOP自动代理 ```java @Configuration @EnableAspectJAutoProxy // 关键注解 public class AppConfig {} ``` ### 二、核心机制解 1. **代理模式原理** - JDK动态代理:基于接口(要求目标类实现接口) - CGLIB代理:基于类继承(适用于无接口的类) - 默认优先使用JDK动态代理,无接口时自动切换CGLIB 2. **通知类型对比** | 通知类型 | 注解 | 执行时机 | |---------------|---------------|-----------------------------| | Before | `@Before` | 目标方法执行前 | | After | `@After` | 目标方法完成(含异常) | | AfterReturning| `@AfterReturning` | 方法成功返回后 | | AfterThrowing | `@AfterThrowing` | 方法抛出异常后 | | Around | `@Around` | 包裹整个方法(必须调用proceed) | 3. **切点表达式语法** ```java // 语法结构:execution(修饰符? 返回类型 包名.类名.方法名(参数) 异常?) @Pointcut("execution(public * com.example.service.*.*(..))") ``` ### 三、典型应用场景 1. **事务管理**:通过`@Transactional`注解实现(本质是AOP) 2. **性能监控**:使用`@Around`统计方法耗时 3. **安全控制**:通过前置通知进行权限校验 4. **日志统一处理**:记录方法入参、返回值、异常 ### 四、常见问题因与解决 1. **拦截失效问题** - 因:非Spring Bean方法调用、private方法、自调用(this.method()) - 解决:使用`ApplicationContext`获取代理对象 2. **循环依赖异常** - 因:AOP代理创建导致依赖关系复杂化 - 解决:避免循环依赖或使用`@Lazy`延迟注入 3. **执行顺序混乱** - 因:多个切面执行顺序不确定 - 解决:使用`@Order`注解指定优先级 ```java @Aspect @Order(1) // 数字越小优先级越高 public class FirstAspect { ... } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值