其他资料
每日速记10道java面试题16-优快云博客
每日速记10道java面试题17-优快云博客
每日速记10道java面试题18-优快云博客
每日速记10道java面试题19-优快云博客
目录
4.Spring AOP默认用的是什么动态代理,两者的区别?
1.Spring Bean 一共有几种作用域?
singleton:默认是单例,含义不用解释了吧,一个IOC 容器内部仅此一个
prototype:原型,多实例
request:每个请求都会新建一个属于自己的 Bean 实例,这种作用域仅存在 Spring Web 应用中session:一个 http session 中有一个 bean 的实例,这种作用域仅存在 Spring Web 应用中application:整个 ServletContext 生命周期里,只有一个 bean,这种作用域仅存在 Spring Web 应用中
websocket:一个 WebSocket 生命周期内一个 bean 实例,这种作用域仅存在 Spring Web 应用中
2.Spring有几种注入方式?
构造器注入: Spring 倡导构造函数注入,因为构造器注入返回给客户端使用的时候一定是完整的。
public class MyService {
private final MyDependency myDependency;
@Autowired
public MyService(MyDependency myDependency) {
this.myDependency = myDependency;
}
}
为什么Spring提倡构造函数注入而不是使用@Autowired?
@Autowired与构造器注入区别,为什么spring推荐使用构造注入而不是Autowired?_autowired 构造器注入-优快云博客
setter 注入:可选的注入方式,好处是在有变更的情况下,可以重新注入。
public class MyService {
private MyDependency myDependency;
@Autowired
public void setMyDependency(MyDependency myDependency) {
this.myDependency = myDependency;
}
}
字段注入:就是平日我们用 @Autowired标记字段
public class MyService {
@Autowired
private MyDependency myDependency;
}
方法注入:就是平日我们用 @Autowired 标记方法
public class MyService {
public void performAction(@Autowired MyDependency myDependency) {
myDependency.doSomething();
}
}
如果觉得构造器注入太繁琐了,还可以使用lombok的@RequireArgsConstructor注解
@RequiredArgsConstructor
public class xxx {
private final UserFormDao userFormDao;
private final UserFormDataDao userFormDataDao;
}
3.什么是AOP?
AOP是面向切面变成,是一种编程范式,用于将跨领域的关注点(如日志记录、安全检查、事务管理等)与业务逻辑分离开来。它允许开发者通过“切面”(Aspect)将这些通用功能模块化,并将其应用到应用程序中的多个地方,从而避免代码重复。
核心思想:AOP 的核心思想是将与业务逻辑无关的横切关注点抽取出来,通过声明的方式动态地应用到业务方法上,而不是将这些代码直接嵌入业务逻辑中。
主要组成部分:AOP包括几个关键概念:切面(Aspect)、连接点(JoinPoint)、通知(Advice)、切入点(Pointcut)和织入(Weaving)。
延伸→AOP有哪些应用场景?
日志记录、事务管理、安全检查、性能监控这些独立于业务逻辑开外的功能都可以用AOP。
4.Spring AOP默认用的是什么动态代理,两者的区别?
Spring:JDK动态代理。
springboot 2.x:CGLIB动态代理
区别:
jdk动态代理,基于接口实现,通过java.ang.reflect.proxy反射技术实现
cglib,基于类继承,通过字节码技术生成目标类的子类。不能代理final类和方法
jdk动态代理实现:
基于Java反射,只能代理实现了接口的类。首先通过InvocationHandler接口得到一个切面类,然后利用Proxy根据目标类的类加载器、接口和切面类得到一个代理类。
cglib动态代理实现:
基于字节码技术,可以代理所有对象。首先通过Methodlnterceptor接口得到一个拦截类,new一个enhancer,传入需要代理的类,创建callback方法并设置拦截类,再使用enhancer.create()方法返回一个代理类,同时这个代理类和方法不能被final修饰。
为什么springboot 用cglib?
jdk动态代理基于接口,没有接口就会报错;而且cglib被打包到spring里面了,就直接用了。
5. 能说说 Spring 拦截链的实现吗?
在 Spring 中,拦载链通常指的是一系列拦截器(如 AOP 切面、过滤器、拦截器等)依次作用于请求或方法调用,实现横切关注点的处理比如日志记录、权限控制、事务管理等。
Spring 拦截链的核心实现包括以下几个方面:
Handlerinterceptor(MVC 拦截器):用于拦截HTTP 请求并进行预处理和后处理。通过实现 HandlerInterceptor 接口的preandle、 postHandle和afterCompletion方法,可以在请求到达控制器之前、控制器方法执行之后以及请求完成后进行处理
Filter (过滤器):基于 Servlet API的过滤器,可对请求进行初步筛选,应用于安全验证、编码过滤、跨域处理等场景。过滤器通过Filter 接口的 foFilter方法拦截请求。
AOP 拦截链(切面):Spring AOP 提供的方法级别的拦截,通过定义切面(Aspect)可以实现方法的前后处理。切面中的 @Before、@After 、@Around 等注解用于控制拦截的执行顺序。
6.说一下Bean的生命周期?
- 实例化:Spring 容器根据配置文件或注解实例化 Bean 对象。
- 属性注入:Spring 将依赖(通过构造器、setter 方法或字段注入)注入到 Bean 实例中。
- 初始化前的扩展机制:如果 Bean 实现了 BeanNameAware 等 aware 接口,则执行 aware 注入。
- 初始化前(BeanPostProcessor):在 Bean 初始化之前,可以通过 BeanPostProcessor 接囗对 Bean 进行一些额外的处理
- 初始化:调用 InitializingBean 接口的 afterPropertiesSet() 方法或通过 init-method 属性指定的初始化方法。
- 初始化后(BeanPostProcessor):在 Bean 初始化后,可以通过 BeanPostProcessor 进行进一步的处理。
- 使用 Bean:Bean 已经初始化完成,可以被容器中的其他 Bean 使用。
- 销毁:当容器关闭时,Spring 调用 DisposableBean 接口的 destroy() 方法或通过 destroy-method 属性指定的销毁方法。
7.说下对 Spring MVC 的理解?
SpringMVC是spring对mvc的实现,对传统的mvc做了扩展,将model层分为了业务模型Service和数据模型Repository,controller层拆分成了前端控制器DispatcherServlet和后端控制器Controller,以前的servlet+jsp的模式,开发要写很多的servlet,现在和Servlet解耦,简化了web开发。
Spring MVc 的工作流程可以分为以下几个关键步骤:
1.客户端请求:浏览器向服务器发送 HTTP 请求。
2.DispatcherServlet:所有的请求首先由 Spring MVC 的核心前端控制器 Dispatcherservlet 接收,它充当整个流程的调度中心。
3.处理器映射 (Handler Mapping): DispatcherServlet根据请求的 URL 使用处理器映射器找到对应的控制器(Controller)。
4.控制器(Controller):控制器接收请求并处理业务逻辑,通常通过注解 @Controller 和 @RequestMapping定义请求的映射方法,
5.模型和视图(ModelAndView):控制器处理完业务逻辑后,将教据封装到模型对象中,并指定返回的视图名称。
6.视图解析器 (ViewResolver): Dispatcherservlet 调用视图解析器,将逻辑视图名称解析为实际的视图,如 JSP、Thymeleaf 等模板引擎。
7.视图渲染:视图渲染引擎根据模型中的数据生成 HTML 页面并返回给客户端。
8.SpringMVC的父子容器你了解吗?
- 父容器是一个顶层的Spring容器,通常用于定义共享的bean和配置,并且所有的子容器都可以访问父容器中定义的bean,适合于定义全局的服务、数据源等。一般是由ContextLoaderListener去加载并初始化父容器。
- 子容器是从父容器派生出来的容器,可以定义自己的bean。子容器可以重写父容器中定义的bean,也可以添加新的bean。适合于模块化的应用程序,例如不同的模块或功能可以有自己的子容器 ,一般是由DispatcherServlet去加载并初始化子容器。
9.你知道Spring中使用了哪些设计模式吗?
- 工厂模式,从名字就能看出来是 BeanFactory,整个 Spring lOc 就是一个工厂模板方法,例如 JdbcTemplate、RestTemplate,名字是 xxxTemplate 的都是模板。
- 代理模式,AOP 整个都是代理模式。
- 单例模式,默认情况下 Bean 都是单例的。
- 责任链模式,比如 Spring MVC 中的拦截器,多个拦截器串联起来就形成了责任链,
- 观察者模式,在 Spring 中的监听器实现。
- 适配器模式,在 Spring MVC 中提到的 handlerAdapter 其实就是适配器,
10.Spring事务有几个隔离级别?
Spring 提供了五种事务隔离级别:
1.DEFAULT(默认):使用底层数据库的默认隔离级别。如果数据库没有特定的设置,通常默认为READCOMITTED。
2.READ UNCOMMITTED(读未提交):最低的隔离级别,允许事务读取尚未提交的数据,可能会导致脏读、不可重复读和幻读
3.READCOMMITTED(读已提交):仅允许读取已经提交的数据,避免了脏读,但可能会出现不可重复读和幻读问题。
4.REPEATABLE READ(可重复读):确保在同一个事务内的多次读取结果一致,避免脏读和不可重复读,但可能会有幻读问题。
5.SERIALIZABLE(可串行化):最高的隔离级别,通过强制事务按顺序执行,完全避免脏读、不可重复读和幻读,代价是性能显著下下降。