java被常问到的面试题之spring篇

Spring框架核心特性包括:
loC容器:即控制反转的意思,它是一种创建和获取对象的技术思想,依赖注入(DI)是实现这种技术的一种方式。传统开发过程中,我们需要通过new关键字来创建对象。使用I0C思想开发方式的话,我们不通过new关键字创建对象,而是将这个控制权交给了外部的容器。这样的好处是:控制反转使得组件之间不直接依赖,而是通过容器管理依赖,降低了对象之间的耦合度,使得资源变的容易管理。
IOC 的实现方式有哪些?
DI(依赖注入):提供依赖
• DI (依赖注入)是 IoC 思想的具体实现方式之一,它通过将对象的依赖从外部提供给对象,而不是在对象内部创建依赖,从而实现控制反转。DI 可以通过构造函数注入、Setter 注入或接口注入。

代码:

点击查看代码
// 依赖类
public class Car {
    private Engine engine;

    // 通过构造器注入依赖
    public Car(Engine engine) {
        this.engine = engine;
    }

    public void start() {
        engine.start();
    }
}

public class Engine {
    public void start() {
        System.out.println("Engine started");
    }
}
<bean id="engine" class="com.example.Engine"/>
<bean id="car" class="com.example.Car">
    <constructor-arg ref="engine"/>
</bean>

AOP
AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,将(如日志、事务管理、安全等)从主要业务逻辑中分离出来,以提高模块化和代码复用性。AOP 将这些关注点封装为 切面(Aspect)。

AOP 的实现方式有哪些?

AOP 的实现方式有 动态代理 和 字节码操作 两种类型。
Spring AOP 就是基于动态代理的,如果要代理的对象,实现了某个接口,那么 Spring AOP 会使用 JDK Proxy,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候 Spring AOP 会使用 Cglib 生成一个被代理对象的子类来作为代理,如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择 AspectJ ,它比 Spring AOP 快很多(代理机制不同,Spring AOP 主要使用代理模式,特别是基于 JDK 动态代理 和 CGLIB 代理 的方式。代理对象会在运行时创建,并拦截方法调用。因此,Spring AOP 的代理对象需要在每次方法调用时进行方法调用的拦截和增强。AspectJ 是在 编译时、类加载时 或 运行时 织入切面代码的。它不像 Spring AOP 那样依赖代理对象的运行时创建,而是将切面直接织入到目标类的方法中。因此,AspectJ 生成的是 增强后的类,没有额外的代理对象存在,直接增强目标方法。)

动态代理是在运行时生成代理对象的机制。代理对象能够拦截目标方法的调用,并进行增强操作。
代理分为:
动态代理
JDK 动态代理
• 原理:通过反射机制,在运行时生成目标类接口的代理类,代理类会拦截对接口方法的调用,并执行通知方法。
• 限制:目标类必须实现接口,JDK 动态代理只能为实现了接口的类创建代理对象。
• 实现方式:java.lang.reflect.Proxy 类和 InvocationHandler 接口。
CGLIB 代理
• 原理:CGLIB(Code Generation Library)是通过字节码操作技术,在运行时动态生成目标类的子类。代理对象会拦截目标类方法的调用,并执行增强操作。
• 限制:目标类不能是 final 类,也不能有 final 方法,因为 CGLIB 是通过继承方式生成代理类的。
• 实现方式:使用 net.sf.cglib.proxy.Enhancer 类来生成代理对象。

2. 字节码操作

字节码操作不通过继承或接口的方式来创建代理,而是直接修改字节码,使得方法的执行被增强。字节码操作通常在类加载时就会进行。
(1) AspectJ 编译时织入
• 原理:AspectJ 是基于字节码操作的 AOP 实现。它在编译时通过 注解处理器(Annotation Processor)或者 AspectJ 编译器(ajc)将切面代码织入目标类中,直接修改字节码。
• 优点:无论目标类是否是 final 类,都可以被增强。织入发生在编译时,因此性能较高。
• 实现方式:通过 AspectJ 编译器 (ajc) 来编译源码并将切面代码织入到目标类的字节码中。
(2) Spring AOP 基于 CGLIB 或 AspectJ 的织入
• 原理:Spring AOP 依赖于 CGLIB 或 AspectJ 来生成代理,这些技术都使用字节码操作。
o CGLIB:通过字节码操作动态生成目标类的子类,实现增强。
o AspectJ:在类加载时或编译时通过字节码操作进行织入。
对于 Spring AOP,如果目标类没有接口,Spring 会使用 CGLIB 代理,这也涉及到字节码操作。

AOP 的应用场景有哪些?

  • 日志记录:自定义日志记录注解,利用 AOP,一行代码即可实现日志记录。
  • 性能统计:利用 AOP 在目标方法的执行前后统计方法的执行时间,方便优化和分析。
  • 事务管理:@Transactional 注解可以让 Spring 为我们进行事务管理比如回滚异常操作,免去了重复的事务管理逻辑。@Transactional注解就是基于 AOP 实现的。
  • 权限控制:利用 AOP 在目标方法执行前判断用户是否具备所需要的权限,如果具备,就执行目标方法,否则就不执行。例如,SpringSecurity 利用@PreAuthorize 注解一行代码即可自定义权限校验。
  • 接口限流:利用 AOP 在目标方法执行前通过具体的限流算法和实现对请求进行限流处理。
  • 缓存管理:利用 AOP 在目标方法执行前后进行缓存的读取和更新。

事务管理:Spring提供了一致的事务管理接口,支持声明式和编程式事务。开发者可以轻松地进行事务管理,而无需关心具体的事务API。
MVC框架:Spring MVc是一个基于Servlet AP!构建的Web框架,采用了模型-视图-控制器(MVC)架构。它支持灵活的URL到页面控制器的映射,以及多种视图技术。

感悟:希望诸君切勿妄自菲薄,尽全力释放自己,看看自己在这个世界的位置。

posted @   史蒂文写不来代码  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示