【Java超高频面试题&Spring】Spring相关高频面试题汇总

简介:

本期文章将汇总Spring相关的高频面试题,给最近需要找工作的朋友们总结一波,帮助大家全面掌握Spring核心知识点,提升竞争力,为你的面试之旅保驾护航!


介绍一下Spring

Spring是一个开源的轻量级控制反转面向切面编程的容器框架。

轻量级是说它开发使用简单,功能强大。

控制反转是指将对象的创建,销毁控制交给ioc容器,方便解耦合,降低维护难度

面向切面编程是指将相同的逻辑横向抽取出来,可以对一些通用业务如事务,日志进行集中管理

说下Spring框架的组成

1. CoreContain 核心容器模块:包括 beans IOC管理,context上下文,SPEL表达式等

2. Web模块:包括SpringMVC基本功能,websocket等

3. data 数据/集成模块:包括JDBC,ORM对象关系映射 ,事务管理, JMS消息功能等

4. 其他模块:AOP ,测试等

什么是Spirng的IOC

IOC控制反转,把对象的创建,属性设置,初始化,销毁等工作交给Spirng的IOC容器去管理,解放程序员的劳动力。

对象被注册到Spring的IOC容器中,

通过依赖注入,将需要的外部资源注入到组件中,使用IOC使得对象之间的耦合度降低,资源变得容易管理,从而使得代码更加优雅。

你对AOP的理解

AOP,意为面向切面编程,是Spring的核心思想之一

AOP是对OOP(面向对象编程)的一种补充,能够做到很多面向对象无法做到的事情,比如需要在所有方法执行前开启事务,打印日志,如果使用面向对象来编程,将会产生大量重复代码,而使用AOP,可以将那些与业务无关,却为业务模块所共同调用的逻辑封装起来,一次解决这些问题。而这些重复的代码,一般统称为横切逻辑代码

使用AOP,在不改变原有业务逻辑的情况下,实现解耦合,避免横切逻辑代码重复

AOP的使用场景包括日志记录,性能统计,安全控制,事务处理,异常处理等等

AOP的原理(使用什么设计模式)

它是基于动态代理实现的,

分为JDK动态代理和CGLIB动态代理。

JDK动态代理只支持实现了接口的类 ,CGLIB支持没有实现接口的类。

Spring默认使用JDK动态代理,如果被代理类没有实现接口,会选择CGLIB动态代理。

另外Spring的AOP还用到了执行链模式。

Spring的Bean懒加载和非懒加载有什么区别

懒加载(惰性加载):需要使用对象的时候才创建,节省资源,但不利于提前发现错误

非懒加载,也叫迫切加载,容器启动时就创建对象,消耗资源,但有利于提前发现错误

spring中默认是迫切加载,即在项目启动时,spring会扫描符合条件的所有bean并将其初始化

如果需要懒加载,可以使用@Lazy注解或者xml中配置属性default-lazy-init="true"

Spring的依赖注入方式有哪些

方式一:setter方式注入,通过反射调用无参构造方法生成对象,再通过对于的setter方法注入配置的值,支持注解和xml两种实现方式

方式二:构造器方式注入,通过反射调用有参构造方法生成对象,支持注解和xml两种实现方式 

注解实现方式:@Autowired,它是默认按类型匹配的、@Resource,它是默认按名字匹配的

说一下定义切面相关的注解

@Aspect:定义切面

@Pointcut:定义切点 = cn.xx.service.*

@Before:前置通知,在目标方法运行之前运行

@After:后置通知,在目标方法运行结束之后运行(无论方法正常结束还是异常结束)

@AfterReturning:返回通知,在目标方法正常返回之后运行

@AfterThrowing:异常通知,在目标方法出现异常以后运行

@Around:环绕通知, 动态代理,手动推进目标方法运行

spring注册bean方式

1. 注册Bean(定义Bean)的注解

@Controller/@RestController 一般用于定义控制层的类

@Service 一般用于定义服务层的类

@Repository 一般用于定义持久层类

@Component 定义一般类

@Configuration 定义配置类

2. @Import方式

搭配 @Configuration使用, @Import({类.class})

@Import({Student.class})
@Configuration
public class AppConfig {
}
3. @Configuration + @Bean方式

@Configuration用来声明一个配置类,然后使用 @Bean 注解声明一个bean,将其加入到Spring容器中。

@Configuration
public class AppConfig {
	@Bean
	public Student student() {
		return new Student();
	}
}
4. FactoryBean

使用FactoryBean工厂bean, 动态构建一个bean实例

实现FactoryBean接口, 复写三个方法

  • 1、getObject():自定义Bean如何创建;
  • 2、getObjectType():要注册的Bean的类型;
  • 3、isSingleton():是否单例;
@Component
public class UserFactoryBean implements FactoryBean<User> {
	@Override
	public User getObject() throws Exception {
		return new User();
	}
	@Override
	public Class<?> getObjectType() {
		return User.class;
	}
	@Override
	public boolean isSingleton() {
		return true;
	}
}

5. 实现ImportSelector接口

动态的批量注入配置类或bean对象, springboot自动装配机制里有用到

单例多例的区别

单例和多例属于对象模式,单例模式指对象在整个系统中只存在一份,多例模式则可以有多个实例。

在spring的ioc容器中的bean默认都是单例的,如果需要使用多例,可以通过修改scope属性:scope="prototype"

如果一个bean是单例模式的,在处理多次请求的时候,在ioc容器中只实例化一个bean,这个对象会被保存在一个ConcurrentHashMap中,当有请求来的时候,会先从map中查看,如果有就直接使用这个对象,没有才会实例化新的对象。

如果是多例(prototype)模式的bean,每次请求来的时候,会直接实例化新的bean,没有map缓存的过程。

Bean被指定为prototype以及singleton有什么区别

这两者分别指的是多例和单例模式,singleton即单例模式,指对象在整个系统中只存在一份;prototype即多例模式系统中可以有多个实例。

如果一个bean是单例模式的,在处理多次请求的时候,在ioc容器中只实例化一个bean,这个对象会被保存在一个ConcurrentHashMap中,当有请求来的时候,会先从map中查看,如果有就直接使用这个对象,没有才会实例化新的对象。

如果是多例模式的bean,每次请求来的时候,会直接实例化新的bean,没有map缓存的过程。

在spring的ioc容器中的bean默认都是单例的,如果需要使用多例,可以指定scope属性:scope="prototype"

BeanFactory和ApplicationContext有什么区别

BeanFactory接口是IOC容器的核心接口,定义了管理bean的最基本方法,比如实例化,配置,管理,获取bean的方法

ApplicationContext接口是BeanFactory接口的子接口,除了继承BeanFactory中所有管理bean的方法,还拥有环境、国际化、资源、事件等服务相关的接口

BeanFactory是延迟加载ApplicationContext是迫切加载

SpringMVC如何对时间格式的参数进行格式化

第一种需求,后台接收前台页面返回的string类型时间,要转换成的Date类型数据,可以使用@DateTimeFormat注解来接收参数

第二种需求,后台将Date类型数据返回给前台页面,默认是返回时间戳,如果想要优雅的格式,可以在模型的Date字段或get方法上使用@JsonFormat注解

SpringMVC常用的注解有哪些

@Controller:用来标识一个类是控制器类

@RequestMapping:用来映射请求路径和参数

@ResponseBody:将返回值放到responsebody中,通常返回json或者xml格式数据

@RequestBody:将前台请求参数转换成对象

@PathVariable:接收路径参数,通常用在restful接口中

@RestController:@Controller和@ResponseBody的组合注解

@ControllerAdvice:运用aop的思想,对全局做一些处理,比如结合@ExceptionHandler做全局异常捕获

如何定义SpringMVC的拦截器

拦截用户的请求并做相应的处理, 通常应用在权限验证、 判断登录等功能上

1. 实现HandlerInterceptor 接口来自定义拦截器

(1) preHandler 请求到达处理器之前执行

(2) postHandler 请求经过处理器之后、解析视图之前执行

(3) afterCompletion 视图渲染之后、返回客户端之前执行

2. 配置文件继承WebMvcConfigurer, 重写addInterceptors方法,注册拦截类,添加和排除相应的请求路径

SpringMVC的执行原理

1.客户端请求提交到DispatcherServlet-前端控制器

2.由DispatcherServlet调用处理映射器-HandlerMapping,根据url找到对应的Handler

Handler,HandlerMethod(例如在springboot中加了@RequestMapping/@PostMapping/@GetMapping...的方法就是handler)

3.DispatcherServlet指定处理器适配器-HandlerAdapter去调用Handler

4.Handler调用业务逻辑处理完成后,返回ModelAndView

5.DispatcherServlet查询到一个或多个视图解析器-ViewResoler,找到ModelAndView指定的视图

6.Http响应:将结果显示到客户端

SpringMVC的Controller是单例还是多例,有没有并发安全问题,如何解决

Controller是单例的,

好处是减少了创建对象和垃圾回收的时间, 节省内存

有并发安全问题

所有请求访问同一个controller时,它其中的成员变量是所有线程公用的,若有线程修改了变量,其他请求来访问变量就是改变后的值

1. 在类上加上@Scope(“prototype”), 将controller变为多例模式

2. 使用ThreadLocal变量,使每个线程有独立的变量

3. 加锁

总之,非必要,最好不要在controller中使用成员变量。

相比Spring,Spring Boot有哪些优点

1. SpringBoot基于Spring, 简化了spring, 开发快, 效率高

2. 简化maven依赖, 管理了大量基础依赖

3. 基于注解配置(javaConfig), 无需xml配置

4. 内嵌tomcat, 部署和打包流程更灵活, 运行独立运行

SpringBoot如何做全局异常处理

1. 编写一个全局异常处理类,加上@ControllerAdvice注解

2. 自定义方法,加上@ExceptionHandler注解来捕获具体的异常并作相应的处理

3. 自定义异常类, 自定义枚举错误码, 封装结果, 异常后,向前台返回一个包含错误码的信息

@SpringBootApplication注解的含义

1. 是springBoot的核心注解,表示该类是主启动类, 目的是开启自动配置

2. 包含三个子标签

(1) @ComponentScan 注解

开启ioc自动扫描,扫描当前及子包中需要交给spring管控的类,将这些bean加载到ioc容器中

(2) @EnableAutoConfiguration 注解

启用springboot 自动配置,自动所有扫描 classpath 目录下jar中的文件实现配置类批量注册

(3) @SpringBootConfiguration 注解

标志该类为springboot 配置类

SpringBoot自动配置原理(重要)

在SpringBoot启动类中有一个 `@SpringBootApplication`注解,他是一个复合(组合)注解,他由三个重要的注解组成

- SpringBootConfiguration : 本质是一个@Configuration 代表当前注解是一个Spring的配置注解,用来标记某一个类是Spring的配置类。

- ComponentScan :IOC注解自动扫描,默认扫描启动类所在包及其子包中贴了`@Service,@Component,@Controller,@Repository,@Configuration `等注解的类,自动注册到Spring容器中。

- EnableAutoConfiguration : 开启自动配置的注解

自动配置的关键是 `@EnableAutoConfiguration` 这个注解, `@EnableAutoConfiguration` 开启自动配置,而该注解上通过 @Import 导入了一个自动配置选择器,它负责去扫描并加载ClsssPath下的jar中的META-INF/spring.facotries 文件中的自动配置类,然后批量注册到Spring容器中。在这些自动配置类中通常使用 @Bean的方式定义需要的Bean。

spring-boot-starter-parent的作用

1. 是SpringBoot 的父工程, 帮我们管理很多基础jar包

2. 同时继承了spring-boot-dependencies, 项目中通过 <dependencyManagement>标签管理了大量的依赖

3. 通过<properties>维护依赖版本号

4. 项目中,还需要通过<dependencies> 去导入具体的依赖才能使用

spring-boot-starter-web的作用

此项目是Springboot 和 Springmvc 整个的 jar 包,

构建了 web 项目的基本环境,

集成了日志,tomcat,springmvc,json 支持等

SpringBoot中如何读取配置

方式一:使用@Value 读取配置文件

方式二:使用@ConfigurationProperties 读取配置文件

你对spring-boot-starter的理解

一个Starter 代表一套环境, starter组件会把对应功能的所有jar包依赖都导入进来, 避免我们去自己引入依赖

一个starter 包中包含了 SpringBoot 的自动装配机制,可以自动初始化好一些必要的 Bean, 集成到spring生态里面。

在开发中我们只需要关心业务逻辑, 减少对配置和外部环境的依赖,这些组件所需要的外部化配置, 直接在application.properties里面进行配置就可以了

怎么封装自己的starter(重要)

  1. 新建一个项目或者包, 导入spring-boot-starter-web依赖
  2. 创建一个类使用@ConfigurationProperties读取yaml的配置
  3. 创建一个Template来封装功能代码
  4. 使用@Configuration创建一个配置类, 使用@EnableConfigurationProperties注解, 引入类,读取配置
  5. 定义Template的Bean, 把配置类传给他
  6. 在resources里面新建META-INFO/spring.factories文件
  7. 在文件中写入要自动装配的类的完全限定名

细节: 注入了原依赖有的类可能会造成类冲突, 使用@ConditionalOnMissingBean(类.class),扫描ioc是否有类,有则不创建


结语

🔥如果文章对你有帮助的话,欢迎💗关注、👍点赞、⭐收藏、✍️评论,支持一下小老弟,蟹蟹大咖们~ 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值