您的位置:首页 > 科技 > IT业 > Spring相关面试题汇总

Spring相关面试题汇总

2024/9/23 5:12:18 来源:https://blog.csdn.net/weixin_44925547/article/details/141234837  浏览:    关键词:Spring相关面试题汇总

文章目录

  • Spring
    • 什么是AOP? 你怎么应用的?底层原理?
    • 什么是IOC?IOC的工作流程?
    • Spring支持哪些注入方式?
    • Spring事务原理,如何开启事务,事务的传播机制有哪些?
    • Spring多线程事务能不能保证一致性?
    • Spring事务失效的原因?
    • 为什么有些公司禁止使用@Transactional声明式事务?
    • Bean的生命周期及常用自定义方法
    • Bean作用域
    • 有两个相同id的Bean会报错吗?
    • 循环依赖问题以及解决办法,什么是三级缓存?
    • Spring用到了哪些设计模式?
  • SpingMVC
    • Spring MVC是什么,核心是什么,它的执行流程?
    • Spring MVC的控制器(bean)是不是单例模式(是不是线程安全)?存在什么问题?如何解决?
  • Springboot
    • 起步依赖、自动配置原理;yml等配置文件的配置优先级
  • 常见注解有哪些? @Autowird 与 @Resource区别;@Component和@Bean区别;@Conditional作用
    • Spring 的常见注解
    • SpringMVC的常见注解
    • Springboot的常见注解
    • @Autowird 与 @Resource的区别
    • @Component和@Bean的区别
    • @Conditional注解作用?
  • 其他
    • 过滤器与拦截器的区别
    • 如何解决跨域问题?
    • 如何让你的Bean在其他Bean加载之前加载?
    • 如何统计一个Bean中方法的调用次数?
    • 如何根据配置动态生成Bean?

Spring

什么是AOP? 你怎么应用的?底层原理?

什么是AOP?
AOP是面向切面编程,在spring中用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取公共模块复用,降低耦合,一般比如可以做为公共日志保存,事务处理等。

你怎么应用的?
我们当时在后台系统中,就是使用aop来记录了系统的操作日志。主要思路是这样的,使用aop中的环绕通知+切点表达式,这个表达式就是要找到要记录日志的方法,然后通过环绕通知的参数获取请求方法的参数,比如类信息、方法信息、注解、请求方式等,获取到这些参数以后,保存到数
据库。

AOP的底层原理?

Spring AOP就是基于动态代理的,如果要代理的对象,实现了某个接口,那么Spring AOP会使用JDKProxy,去创
建代理对象, 而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候Spring AOP会使用基于
asm框架字节流的Cglib动态代理 ,这时候Spring AOP会使用 Cglib 生成一个被代理对象的子类来作为代理。

AOP当中涉及到的一些核心概念:

  • 连接点:JoinPoint,可以被AOP控制的方法
  • 通知:Advice,指哪些重复的逻辑,也就是共性功能(最终体现为一个方法)
  • 切入点:PointCut,匹配连接点的条件,通知仅会在切入点方法执行时被应用
    切面:Aspect,描述通知与切入点的对应关系(通知+切入点就形成了一个切面)
    目标对象:Target,通知所应用的对象

Spring中AOP的通知类型:

  • @Around:环绕通知,此注解标注的通知方法在目标方法前、后都被执行
  • @Before:前置通知,此注解标注的通知方法在目标方法前被执行
  • @After :后置通知,此注解标注的通知方法在目标方法后被执行,无论是否有异常都会执行
  • @AfterReturning : 返回后通知,此注解标注的通知方法在目标方法后被执行,有异常不会执行
  • @AfterThrowing : 异常后通知,此注解标注的通知方法发生异常后执行

JDK动态代理只提供接口的代理,不支持类的代理。

  • JDK会在运行时为目标类生成一个动态代理类$proxy*.class .
  • 该代理类是实现了目标类接口,并且代理类会实现接口所有的方法增强代码
  • 调用时先去调用处理类进行增强,再通过反射的方式进行调用目标方法,从而实现AOP。

如果代理类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。

  • CGLIB的底层是通过ASM(一种用于直接生成或修改字节码的框架,全称为 “Abstract Syntax Notation One”)在运行时动态的生成目标类的一个子类。(还有其他相关类)会生成多个。
  • 并且会重写父类所有的方法增强代码,
  • 调用时先通过代理类进行增强,再直接调用父类对应的方法进行调用目标方法。从而实现AOP。
  • CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。
  • CGLIB除了生成目标子类代理类,还有一个FastClass(路由类),可以(但不是必须))让本类方法调用进行增强,而不会像jdk代理那样本类方法调用增强会失效。

JDK动态代理生成类速度快,调用慢,CGLIB生成类速度慢,但后续调用快。就二者的效率来说,大部分情况都是 JDK 动态代理更优秀,随着 JDK 版本的升级,这个优势更加明显。

JDK动态代理实现:

  1. .创建一个实现 InvocationHandler 接口的代理处理器类,重写 invoke() 方法,在该方法中执行额外的逻辑,并调用被代理对象的方法。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;public class MyInvocationHandler implements InvocationHandler {private Object target;public MyInvocationHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 执行额外的逻辑System.out.println("Before method " + method.getName());// 调用被代理对象的方法Object result = method.invoke(target, args);// 执行额外的逻辑System.out.println("After method " + method.getName());return result;}
}
  1. 使用 Proxy.newProxyInstance() 方法创建代理对象。
import java.lang.reflect.Proxy;public class Main {public static void main(String[] args) {RealSubject realSubject = new RealSubject();InvocationHandler handler = new MyInvocationHandler(realSubject);Subject proxySubject = (Subject) Proxy.newProxyInstance(RealSubject.class.getClassLoader(),RealSubject.class.getInterfaces(),handler);proxySubject.request();}
}

CGLIB 动态代理实现:

  1. 创建一个实现 MethodInterceptor 接口的代理处理器类,重写 intercept() 方法,在该方法中执行额外的逻辑,并调用被代理对象的方法。
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com