说说你对Spring的AOP机制的理解可以吗?

AOP是面向切面编程( Aspect)

简单的说就是把我们重复的代码抽取出来,在需要执行的时候,使用动态代理技术,在不修改源码的基础上,对我们已有的方法进行增强

AOP的作用和优势

作用:在程序运行期间,不修改源码对已有方法进行增强。

优势:减少重复代码,提高开发效率,维护方便

AOP的实现方式:使用动态代理技术

 

事务

MySQL、数据库里都提供一个事务机制,我们如果开启一个事务,在这个事务里执行多条增删改的sql语句,这个过程中,如果任何一个sql语句失败了,会导致这个事务的回滚,把其他sql做的数据更改都回复回去。

在一个事务中的所有sql,要么一起成功,要么一起失败。事务功能可以保证我们的数据的一致性,在业务逻辑里加入这个事务

思考:

几十个地方需要写重复性的代码,比如:创建事务、回滚或提交事务的代码,可以使用springAOP机制

 

MyServiceXXXX的这种类,在这些类的所有方法中,都去织入一些代码,在所有这些方法刚开始运行的时候,都先去开启一个事务,在所有这些方法运行完毕之后,去根据是否抛出异常来判断一下,如果抛出异常,就回滚事务,如果没有异常,就提交事务 => AOP

AOP的核心技术是动态代理,会对你的那些类生成动态代理

动态代理:

比如说有个MyServiceA的类,spring会动态生成一个ProxyMyServiceA的动态代理类,会将MyServiceA注入进去。

当Controller注入MyServiceA的时候,spring会将动态代理类ProxyMyServiceA的对象注入,会直接调用ProxyMyServiceA代理类中的方法。

 

【评论区】

1、他人总结

aop:面向切面,通过动态代理的方式来生成其代理对象在方法执行前后加入自己的逻辑

代理方式

jdk动态代理(接口)

cglib动态代理(基于类)

相关名词:

(1) JoinPoint连接点:拦截的接口的方法

(2) Pointcut切入点:对哪些连接点进行拦截

(3)Advice通知:比如前置通知 后置通知 环绕通知

(4) aspect切面:切入点和通知组成 - 切入点 execution表达式 1. execution 权限修饰符 返回值类型 包名.类名.方法名(参数) -

通知类型

(1)前置通知:方法执行之前

(2)后置通知:在方法正常执行完毕后(提交事务)

(3)最终通知:在方法正常执行完毕或者出现异常

(4)异常通知:执行过程中出现异常(事物回滚)

(5)环绕通知:方法执行前后,目标方法默认不执行需自己调用方法

2、今天去面试问了我一个问题:网关灰度发布的时候,app->网关->api服务->dubbo服务,网关是可以灰度选择API服务,如果是dubbo服务呢,如何进行灰度?

您看我这样回答可对,API服务里指定新版本的dubbo服务,灰度请求到指定的API服务后,该服务里本身指定了dubbo接口的新版本,所以能够选中灰度的这台dubbo服务。

没啥问题,dubbo灰度建议通过group去区分dubbo的调用因为版本号的变化让业务人员认为这是对上一个版本的迭代语义上是有歧义的;然后dubbo服务灰度的同时上次调用的api其实也是灰度的因为代码不一样了,也需要通过网关来配置api灰度的权重

3、spring ioc注入的时候,代理对象和被代理对象是怎么选择的?

4、为什么spring aop 要基于接口实现动态代理呢?

AOP使用JDK动态代理的话是需要基于接口的,通过反射去构造代理对象的时候,一个必要参数就是接口类型,因为需要代理类与被代理类有相同的目标方法

 

 

### Spring 框架启动过程 Spring 框架启动时,首先会读取配置文件(XML、Java 注解等),创建并初始化 `ApplicationContext` 容器。容器会解析配置元数据,将定义的 Bean 注册到 Bean 工厂中,然后实例化单例 Bean,对 Bean 进行依赖注入,完成 Bean 的初始化工作,最终使 Spring 应用可以正常运行。 ### Spring 用到的设计模式 - **工厂模式**:`BeanFactory` 和 `ApplicationContext` 就是工厂模式的体现,用于创建和管理 Bean 对象。 - **单例模式**:Spring 中的单例 Bean 默认使用单例模式,保证一个 Bean 在整个应用中只有一个实例。 - **代理模式**:AOP 功能使用代理模式,通过创建代理对象来增强目标对象的功能。 - **观察者模式**:Spring 中的事件机制使用了观察者模式,当一个事件被发布时,所有注册的监听器会收到通知并做出相应处理。 - **模板方法模式**:如 `JdbcTemplate` 等模板类,封装了重复的操作步骤,将具体的业务逻辑交给子类实现。 ### Spring 事务传播行为 - **REQUIRED**:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是最常用的传播行为。 - **SUPPORTS**:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务方式执行。 - **MANDATORY**:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。 - **REQUIRES_NEW**:创建一个新的事务,如果当前存在事务,则将当前事务挂起。 - **NOT_SUPPORTED**:以非事务方式执行操作,如果当前存在事务,则将当前事务挂起。 - **NEVER**:以非事务方式执行操作,如果当前存在事务,则抛出异常。 - **NESTED**:如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则创建一个新的事务。 ### Spring Boot 启动流程 Spring Boot 启动时,`SpringApplication` 类会进行一系列初始化操作,包括加载应用上下文环境、创建 `ApplicationContext` 容器、加载自动配置类、扫描并注册 Bean 等。最后,启动嵌入式服务器(如 Tomcat、Jetty 等),使应用可以处理 HTTP 请求。 ### Spring Boot 自动配置原理 Spring Boot 基于约定优于配置的原则,通过 `@EnableAutoConfiguration` 注解开启自动配置功能。在启动时,Spring Boot 会扫描 classpath 下的 `META-INF/spring.factories` 文件,加载其中定义的自动配置类。这些自动配置类会根据应用的依赖和配置,自动为应用提供默认的配置,减少开发者的手动配置工作。 ### Spring Boot starter 概念 Spring Boot starter 是一组依赖的集合,它将常用的依赖打包在一起,方便开发者快速集成某个功能。例如,`spring-boot-starter-web` 包含了 Spring MVC、嵌入式服务器等开发 Web 应用所需的依赖。开发者只需要引入相应的 starter,Spring Boot 会自动处理依赖关系和配置。 ### Spring Boot 通过 main 方法启动 web 项目的方式 在 Spring Boot 项目中,通常会有一个带有 `@SpringBootApplication` 注解的主类,其中包含 `main` 方法。示例代码如下: ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } } ``` 在 `main` 方法中,调用 `SpringApplication.run` 方法启动 Spring Boot 应用。 ### Spring Boot 核心特性 - **自动配置**:减少开发者的手动配置工作,根据应用的依赖自动提供默认配置。 - **起步依赖**:通过 starter 简化依赖管理,快速集成常用功能。 - **嵌入式服务器**:支持嵌入式的 Tomcat、Jetty 等服务器,方便开发和部署。 - **Actuator**:提供应用监控和管理功能,如健康检查、性能指标监控等。 - **命令行界面(CLI)**:可以使用 Spring Boot CLI 快速创建和运行 Spring Boot 应用。 ### Spring Boot 概念 Spring Boot 是 Spring 社区为了简化 Spring 应用开发而推出的框架,它遵循约定优于配置的原则,极大降低了 Spring 使用门槛,同时保留了 Spring 原本强大灵活的功能。Spring Boot 提供了自动配置、起步依赖等特性,使开发者可以更快速地构建和部署应用。 ### Spring IOC 概念 Spring IOC(Inversion of Control,控制反转)是 Spring 框架的核心特性之一。它将对象的创建、依赖关系的管理从应用代码中分离出来,交给 Spring 容器来完成。通过 IOC,对象之间的依赖关系由容器负责注入,降低了代码的耦合度,提高了代码的可维护性和可测试性。 ### Spring AOP 默认动态代理及区别 Spring AOP 默认使用两种动态代理方式:JDK 动态代理和 CGLIB 动态代理。 - **JDK 动态代理**:基于接口实现,要求目标对象必须实现至少一个接口。它通过 `java.lang.reflect.Proxy` 类创建代理对象,在运行时动态生成代理类。 - **CGLIB 动态代理**:基于继承实现,通过生成目标对象的子类来创建代理对象。它可以对没有实现接口的类进行代理,但不能对 `final` 类和 `final` 方法进行代理。 ### AOP 概念 AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,它允许开发者在不修改原有业务逻辑的基础上,对程序进行增强。AOP 通过将横切关注点(如日志记录、事务管理等)与核心业务逻辑分离,提高了代码的可维护性和可复用性。在 Spring 中,AOP 主要通过代理模式实现。 ### Spring 重要模块组成 - **Spring Core**:提供了 Spring 框架的核心功能,如 IOC 容器、Bean 管理等。 - **Spring AOP**:实现了面向切面编程功能,通过代理模式增强目标对象的功能。 - **Spring Data Access**:提供了数据访问相关的功能,如 JDBC、ORM(如 Hibernate、JPA 等)支持。 - **Spring Web**:包含了 Spring MVC 框架,用于开发 Web 应用。 - **Spring Test**:提供了测试支持,方便开发者对 Spring 应用进行单元测试和集成测试。 - **Spring Security**:用于实现应用的安全认证和授权功能。 - **Spring Boot**:简化 Spring 应用开发,提供自动配置、起步依赖等特性。 ### Spring 循环依赖概念 循环依赖是指两个或多个 Bean 之间相互依赖,形成一个循环。例如,Bean A 依赖 Bean B,而 Bean B 又依赖 Bean A。如果不进行处理,会导致 Bean 初始化时出现死循环,无法完成初始化。 ### Spring 解决循环依赖的方法 Spring 通过三级缓存来解决循环依赖问题。在 Bean 初始化过程中,当一个 Bean 被创建时,会先将其提前暴露到三级缓存中。当其他 Bean 依赖该 Bean 时,可以从三级缓存中获取该 Bean 的早期引用,避免死循环。 ### Spring 循环依赖使用三级缓存的原因 使用三级缓存的主要原因是为了在保证 Bean 正常初始化的同时,支持 AOP 功能。如果只使用一级缓存,无法处理 AOP 代理对象的循环依赖问题。通过三级缓存,可以在 Bean 还未完全初始化时,提前暴露其早期引用,同时在需要时创建代理对象,保证 Bean 的正常初始化和功能增强。 ### Spring Bean 生命周期 Spring Bean 的生命周期包括以下几个阶段: 1. **实例化**:通过反射创建 Bean 对象。 2. **属性赋值**:对 Bean 的属性进行依赖注入。 3. **初始化**:调用 Bean 的初始化方法,如 `InitializingBean` 接口的 `afterPropertiesSet` 方法或自定义的初始化方法。 4. **使用**:Bean 可以被应用使用。 5. **销毁**:当 Bean 不再使用时,调用销毁方法,如 `DisposableBean` 接口的 `destroy` 方法或自定义的销毁方法。 ### Spring MVC 工作原理 Spring MVC 是基于 Servlet 的一个 MVC 框架,主要解决 Web 开发问题。其工作原理如下: 1. **客户端发送请求**:客户端向服务器发送 HTTP 请求。 2. **DispatcherServlet 接收请求**:`DispatcherServlet` 作为前端控制器,接收所有请求。 3. **HandlerMapping 查找处理器**:`DispatcherServlet` 根据请求的 URL,通过 `HandlerMapping` 查找对应的处理器(如 Controller 方法)。 4. **HandlerAdapter 调用处理器**:`DispatcherServlet` 通过 `HandlerAdapter` 调用处理器方法,处理请求。 5. **处理器处理请求**:处理器方法处理请求,并返回 `ModelAndView` 对象。 6. **ViewResolver 解析视图**:`DispatcherServlet` 根据 `ModelAndView` 中的视图名称,通过 `ViewResolver` 解析出具体的视图对象。 7. **视图渲染**:`DispatcherServlet` 将模型数据传递给视图对象,进行视图渲染,生成 HTML 页面。 8. **响应客户端**:将渲染后的 HTML 页面返回给客户端。 ### Spring DI 概念 Spring DI(Dependency Injection,依赖注入)是 IOC 的具体实现方式。它通过将对象的依赖关系从对象内部转移到外部,由 Spring 容器负责将依赖对象注入到目标对象中。依赖注入可以通过构造函数注入、Setter 方法注入等方式实现。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值