首页
题库
公司真题
专项练习
面试题库
在线编程
面试
面试经验
AI 模拟面试
简历
求职
学习
基础学习课
实战项目课
求职辅导课
专栏&文章
竞赛
我要招人
发布职位
发布职位、邀约牛人
更多企业解决方案
AI面试、笔试、校招、雇品
HR免费试用AI面试
最新面试提效必备
登录
/
注册
牛客715775713号
中华女子学院 Java
关注
已关注
取消关注
@黎笛:
【八股文】Spring系列
1.Spring的优点2.Spring用了哪些设计模式3.什么是ioc4.ioc容器初始化过程5.Bean的生命周期6.Bean的作用域7.BeanFactory和FactoryBean的区别8.什么是aop9.aop有哪些实现方式10.aop相关术语11.aop原理(源码分析)12.Spring通知有哪些类型13.Spring事务14.什么是SpringMVC15.SpringMVC的主要组件16.请描述一下SpringMVC的工作流程,描述一下DispatcherServlet的工作流程17.拦截器Interceptor和过滤器Filter的区别18.SpringBoot自动装配19.SpringBoot启动流程1.Spring的优点轻量,基本版本大约2MB。 通过控制反转和依赖注入实现松耦合。 支持面向切面的编程,并且把应用业务逻辑和系统服务分开。 通过切面和模板减少样板式代码。 方便集成各种优秀框架。内部提供了对各种优秀框架的直接支持(如:Hibernate、MyBatis等)。方便程序的测试。Spring支持Junit4,添加注解便可以测试Spring程序。Spring的两大核心ioc(控制反转):他就是不会直接创建对象,而是把对象声明出来,把创建对象的权力交给容器,这么做的目的主要是为了解耦ioc原理:工厂模式 + 反射ioc初始化的时候,先去加载配置文件,然后解析配置文件,Spring就知道扫哪些路径(类)了,Spring就把这些类加载成BeanDefinition(定义Bean的配置元信息接口),生成Spring Bean。然后通过反射进行装配(就知道哪些字段需要注入哪些Bean了)aop(面向切面):将公共逻辑封装成切面,跟业务代码进行分离,可以减少系统的重复代码和降低模块之间的耦合。比如日志处理aop原理:动态代理2.Spring用了哪些设计模式简单工厂模式:BeanFactory,跟据传入的唯一一个标识来获取Bean对象工厂方法模式:FactoryBean3.什么是ioc控制反转,把创建对象的权力交给容器,松耦4.ioc容器初始化过程Spring IOC容器初始化的关键环节就在AbstractApplicationContext#refresh()方法,主要方法都是在refresh()方法中完成@Override(992988)public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 第⼀步:刷新前的预处理 prepareRefresh(); /* 第⼆步: 获取BeanFactory;默认实现是DefaultListableBeanFactory 加载BeanDefition 并注册到 BeanDefitionRegistry */ ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 第三步:BeanFactory的预准备⼯作(BeanFactory进⾏⼀些设置,⽐如context的类加载器等) prepareBeanFactory(beanFactory); try { // 第四步:BeanFactory准备⼯作完成后进⾏的后置处理⼯作 postProcessBeanFactory(beanFactory); // 第五步:实例化并调⽤实现了BeanFactoryPostProcessor接⼝的Bean invokeBeanFactoryPostProcessors(beanFactory); // 第六步:注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执⾏ registerBeanPostProcessors(beanFactory); // 第七步:初始化MessageSource组件(做国际化功能;消息绑定,消息解析); initMessageSource(); // 第⼋步:初始化事件派发器 initApplicationEventMulticaster(); // 第九步:⼦类重写这个⽅法,在容器刷新的时候可以⾃定义逻辑 onRefresh(); // 第⼗步:注册应⽤的监听器。就是注册实现了ApplicationListener接⼝的监听器bean registerListeners(); /* 第⼗⼀步: 初始化所有剩下的⾮懒加载的单例bean 初始化创建⾮懒加载⽅式的单例Bean实例(未设置属性) 填充属性 初始化⽅法调⽤(⽐如调⽤afterPropertiesSet⽅法、init-method⽅法) 调⽤BeanPostProcessor(后置处理器)对实例bean进⾏后置处 */ finishBeanFactoryInitialization(beanFactory); /* 第⼗⼆步: 完成context的刷新。主要是调⽤LifecycleProcessor的onRefresh()⽅法,并且发布事件 (ContextRefreshedEvent) */ finishRefresh(); }}5.Bean的生命周期 1)Spring对bean进行实例化 2)Spring将值和bean的引用注入到bean对应的属性中 3)如果bean实现了BeanNameAware接口,Spring将bean的ID传递给setBean-Name()方法; 4)如果bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入; 5)如果bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext()方法,将bean所在的应用上下文的引用传入进来 6)如果bean实现了BeanPostProcessor接口,Spring将调用它们的post-ProcessBeforeInitialization()方法 7)如果bean实现了InitializingBean接口,Spring将调用它们的afterPropertiesSet()方法,进行属性设置。类似地,如果bean使用initmethod声明了初始化方法,该方法也会被调用 8)如果bean实现了BeanPostProcessor接口,Spring将调用它们的post-ProcessAfterInitialization()方法 9)此时bean已经准备就绪,可以被应用程序使用了,他们将一直驻留在应用上下文中,直到该应用上下文被销毁 10)如果bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法。同样,如果bean使用destroy-method声明了销毁方法,该方法也会被调用6.Bean的作用域1)singleton(单例):Spring中的bean默认都是单例的。2)prototype(原型):每次请求都会创建一个新的bean实例。3)request:每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。4)session:每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP session内有效。5)global-session:全局session作用域。Bean是否为线程安全的?原型:线程安全的单例:分为无状态bean和有状态bean有状态的bean在多线程的环境下不安全(业务逻辑对单例的成员属性有修改),一般用prototype模式或者使用threadlocal解决线程安全问题。7.循环依赖怎么解决通过三层缓存第一层:初始化后的Bean第二层:创建好了,但没有初始化的Bean第三层:创建Bean的工厂对象A和BA创建过程中,发现需要B,A就先将自己放到了三级缓存,然后去实例化B了B实例化的时候发现没有A,先查一级缓存,没有,再去查二级缓存,没有,查三级缓存,找到了A然后把三级缓存里面的A放到二级缓存里面,并删除三级缓存里面的AB顺利初始化后,将自己放到一级缓存,此时B已经创建完成,然后继续创建A,A现在可以从一级缓存里拿到B了,A也就可以创建完成了7.BeanFactory和FactoryBean的区别BeanFactory:管理Bean的容器,Spring生成Bean都是由这个接口的实现来管理的FactoryBean:通常是用来创建比较复杂的bean,一般的bean 直接用xml配置即可,但如果一个bean的创建过程中涉及到很多其他的bean 和复杂的逻辑,直接用xml配置比较麻烦,这时可以考虑用FactoryBean,可以隐藏实例化复杂Bean的细节。8.什么是aop面向切面编程,作为面向对象的一种补充,讲公共逻辑(事务管理,日志,缓存)封装成切面,跟业务代码进行分离,可以减少系统的重复代码和降低模块之间的耦合度。9.aop有哪些实现方式静态代理和动态代理静态代理:代理类在编译阶段生成,在编译阶段将通知织入Java字节码中,也称编译时增强。AspectJ使用的是静态代理。动态代理:代理类在程序运行时创建,AOP框架不会去修改字节码,而是在内存中临时生成一个代理对象,在运行期间对业务方法进行增强,不会生成新类。10.aop相关术语切面(Aspect):切面是通知和切点的结合。通知和切点共同定义了切面的全部内容连接点(join point):指方法,在Spring AOP中,一个连接点总是代表一个方法的执行。连接点是在应用执行过程中能够插入切面的一个点。通知(Advice):切面的工作被称为通知织入(weaving):织入是把切面应用到目标对象并创建新的代理对象的过程。在目标对象的生命周期里有以下时间点可以进行织入:1)编译器:切面在目标类编译时被织入。AspectJ的织入编译器是以这种方式织入切面的。2)类加载期:切面在目标类加载到JVM时被织入。需要特殊的类加载器,它可以在目标类被引入应用之前增强该目标类的字节码。AspectJ5的加载时织入就支持以这种方式织入切面。 3)运行期:切面在应用运行的某个时刻被织入。一般情况下,在织入切面时,AOP容器会为目标对象动态地创建一个代理对象。SpringAOP就是以这种方式织入切面。11.aop原理(源码分析)如果我们为spring的某个bean配置了切面,那么spring在创建这个bean的时候,实际上创建的是这个bean的代理对象,我们后续对bean中方法的调用,实际上调用的是代理类重写的代理方法。12.Spring通知有哪些类型通知实际上是程序运行时要通过Spring AOP框架来触发的代码段Spring切面可以应用5种类型的通知:前置通知(Before):在目标方法被调用之前调用通知功能; 后置通知(After):在目标方法完成之后调用通知,此时不会关心方法的输出是什么; 返回通知(After-returning ):在目标方法成功执行之后调用通知; 异常通知(After-throwing):在目标方法抛出异常后调用通知; 环绕通知(Around):通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的逻辑。13.Spring事务spring支持的事务管理类型有两种:编程式事务管理:通过编程的方式管理事务,灵活性好,但是难维护声明式事务管理(常用):将业务代码和事务管理隔离,只需用注解和XML配置来管理事务(主要是通过注解@Transactional)其实事务操作就是AOP的一个核心体验,当一个方法添加@Transactional注解之后,spring会基于这个类生成一个代理对象,会将这个代理对象作为bean,当使用这个代理对象的方法的时候,如果有事务处理,那么会先把事务的自动提交给业务,然后就执行具体逻辑,如果没有异常就直接提交,出现异常就进行回滚。spring事务传播行为解决 多个事务方法相互调用时,事务如何在在这方法中传播14.什么是SpringMVCSpringMVC是一个基于Java,实现了MVC设计模式的请求驱动类型的轻量级Web框架。通过把模型(Model)-视图(View)-控制器(Controller)分离,将web层进行解耦,把复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合它解决了WEB开发中常见的问题(参数接收,文件上传,表单校验,国际化),支持Restful风格的url请求15.SpringMVC的主要组件1).HandlerMapping(处理器映射器)是用来查找Handler的,标注了@RequestMapping的每个方法都可以看成一个Handler,Handler负责具体实际的请求处理,在请求达到后,HandlerMapping的作用便是找到请求相应的处理器Handler和Interceptor2).HandlerAdapter(处理器适配器)要让固定的Servlet处理方法调用Handler来进行处理当HandlerMapping获取了定位请求处理器Handler,DispatcherServlet会将得到的Handler告知HandlerAdapter,HandlerAdapter再根据请求去定位请求的具体处理方法是哪一个3).HandlerExceptionResolver用于处理Handler产生的异常清空。它的作用是跟据异常设置ModelAndView,之后交给渲染方法进行渲染,渲染方法会将ModelAndView渲染成页面4).ViewResolver(视图解析器)找到渲染的模板(第一件大事)和所用的技术(第二件大事,其实就是找到视图的类型,如jsp)5).RequestToViewNameTranslatorRequestToViewNameTranslator 组件的作⽤是从请求中获取 ViewName.因为 ViewResolver 根据ViewName 查找 View,但有的 Handler 处理完成之后,没有设置 View,也没有设置 ViewName,便要通过这个组件从请求中查找 ViewName。6).LocaleResolverViewResolver 组件的 resolveViewName ⽅法需要两个参数,⼀个是视图名,⼀个是 Locale。LocaleResolver ⽤于从请求中解析出 Locale,⽐如中国 Locale 是 zh-CN,⽤来表示⼀个区域。这个组件也是 i18n 的基础。7).ThemeResolver是⽤来解析主题的。主题是样式、图⽚及它们所形成的显示效果的集合。8).MultipartResolverMultipartResolver ⽤于上传请求,通过将普通的请求包装成 MultipartHttpServletRequest 来实现。MultipartHttpServletRequest 可以通过 getFile() ⽅法 直接获得⽂件。如果上传多个⽂件,还可以调⽤ getFileMap()⽅法得到Map<FileName,File>这样的结构,MultipartResolver 的作⽤就是封装普通的请求,使其拥有⽂件上传的功能。9).FlashMapManagerFlashMap ⽤于重定向时的参数传递,⽐如在处理⽤户订单时候,为了避免重复提交,可以处理完post请求之后重定向到⼀个get请求,这个get请求可以⽤来显示订单详情之类的信息。16.请描述一下SpringMVC的工作流程,描述一下DispatcherServlet的工作流程(1)用户发送请求至前端控制器DispatcherServlet;(2) DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handler;(3)处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;(4)DispatcherServlet 调用 HandlerAdapter处理器适配器;(5)HandlerAdapter 经过适配调用 具体处理器(Handler,也叫后端控制器);-------这里才去了controller的handler(6)Handler执行完成返回ModelAndView;-------handler执行完毕,要把数据返回给前端了(7)HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;(8)DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;VIewResolver的作用:找到渲染的模板(第一件大事)和所用的技术(第二件大事,其实就是找到视图的类型,如jsp)(9)ViewResolver解析后返回具体View;(10)DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)(11)DispatcherServlet响应用户。17.拦截器Interceptor和过滤器Filter的区别过滤器是servlet中的接口,主要可以用于在请求进入servlet之前拦截请求HttpServletRequest并跟据需要进行一些检查等逻辑操作,也可以在HttpServletResponse返回客户端之前进行一些逻辑操作。作用是用于对传入的request和响应的response进行进行一些处理,比如对请求参数进行校验,或者设置,检验头部信息,再或者进行一些非法行为校验拦截器是Servlet中的接口,所以它可以获取到spring中的一些bean和其他资源,在面向切面编程中应用比较广,拦截其实就是一种AOP思想18.SpringBoot自动装配1)@SpringBootApplication2)@EnableAutoConfiguration //启动自动配置功能,其实就是借助@Import来收集所有符合自动配置条件的bean定义,并加载到ioc容器3)上面这个是一个组合注解,包含两个注解如下:@AutoConfigurationPackage //自动配置包里面包含了@Import({Registrar.Class}),它就是将Registrar这个组件导入到容器中,可查看Registrar类中的registerBeanDefinitions就是导入组件类的具体实现@Import({AutoConfigurationImportSelector.class}) //自动配置类扫描导入AutoConfigurationImportSelector可以帮助springboot应用将所有符合条件的@Configuration配置到加载到当前springboot创建并使用的ioc容器如果继续研究这个方法,追踪过去,可以看到AutoConfigurationImportSelector类是通过selectImports方法执行,使用内部工具类SpringFactoriesLoader,查找classpath上所有jar包中的/META-INF/spring.factories进行加载,19.SpringBoot启动流程通过run方法,做两件事情1)SpringApplication实例的初始化创建2)调用run()启动项目详细可看源码:SpringApplication初始化:我们逐步分析:第一步:用于判断当前webApplicationType应用的类型。deduceFromClasspath()方法用于查看Classpath类路径下是否存在某个特征类,从而判断当前webApplicationType类型是servlet应用(spring5之前的传统MVC应用)还是reactive应用(spring5开始出现的WebFlux交互式应用)第二步:在初始化器设置过程中,会使用Spring类加载器SpringFactoriesLoader从META-INF/spring.factories类路径下的spring.factories文件中获取所有的可用初始化器ApplicationContextInitializer第三步:类似上一步,从spring.factories文件中获取所有可用的监听器类ApplicationListener第四步:设置项目启动类run()启动运行:public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList(); this.configureHeadlessProperty(); // 第一步:获取并启动监听器 SpringApplicationRunListeners listeners = this.getRunListeners(args); listeners.starting(); Collection exceptionReporters; try { ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); // 第二步:根据SpringApplicationRunListeners以及参数来准备环境 ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments); this.configureIgnoreBeanInfo(environment); // 准备Banner打印器 - 就是启动Spring Boot的时候打印在console上的ASCII艺术字体 Banner printedBanner = this.printBanner(environment); // 第三步:创建Spring容器 context = this.createApplicationContext(); exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, new Object[]{context}); // 第四步:Spring容器前置处理 this.prepareContext(context, environment, listeners, applicationArguments, printedBanner); // 第五步:刷新容器 this.refreshContext(context); // 第六步:Spring容器后置处理 this.afterRefresh(context, applicationArguments); stopWatch.stop(); if(this.logStartupInfo) { (new StartupInfoLogger(this.mainApplicationClass)) .logStarted(this.getApplicationLog(), stopWatch); } // 第七步:发出结束执行的事件 listeners.started(context); // 返回容器 this.callRunners(context, applicationArguments); } catch (Throwable var10) { this.handleRunFailure(context, var10, exceptionReporters, listeners); throw new IllegalStateException(var10); } try { listeners.running(context); return context; } catch (Throwable var9) { this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null); throw new IllegalStateException(var9); } }20.Starerstarer相当于模块,它能将模块所需的依赖整合起来并对模块内的bean跟据环境进行自动配置。使用者只需要依赖相应功能的starer。原理:主要还是基于它提供的起步依赖和自动配置起步依赖:其实就是将具备某种功能的坐标打包到一起,可以简化依赖导入的过程。自动配置:就是无须手动配置xml,自动配置并管理bean,可以简化开发过程。
点赞 13
评论 2
全部评论
推荐
最新
楼层
暂无评论,快来抢首评~
相关推荐
08-12 11:40
门头沟学院 Java
快手秋招笔试
为啥流程从对勾变成省略号了...二面完后,官网上业务2面本来是对勾,今天一看变成省略号了,这是被横向了?
投递快手等公司10个岗位
点赞
评论
收藏
分享
08-12 15:15
广东工业大学 材料工程师
我也接到offer啦
机械岗~感谢tp
小花的沉默:
广工拿到的我直接开吃
点赞
评论
收藏
分享
07-28 00:10
已编辑
门头沟学院 算法工程师
我的天,凌晨还在发消息😅
码农索隆:
这哥们库库在我帖子下评论
点赞
评论
收藏
分享
07-18 11:59
The University of Sydney 算法工程师
也是让我碰见吃人血的公司了
#boss直聘# #当下环境,你会继续卷互联网,还是看其他行业机会#
当下环境,你会继续卷互联...
点赞
评论
收藏
分享
08-14 16:17
门头沟学院 硬件开发
拓竹硬件已挂
拓竹科技的硬件测试岗位已经挂了,希望我投的第一志愿能过
投递拓竹科技等公司10个岗位
点赞
评论
收藏
分享
评论
点赞成功,聊一聊 >
点赞
收藏
分享
评论
提到的真题
返回内容
全站热榜
更多
1
...
小红书java一面
4815
2
...
快手秋招-后端一面
3668
美团第二批笔试
热聊中
3
...
该不该给领导买东西啊...
3574
4
...
美团今天的ai coding笔试允许用ai吗
3154
5
...
秋招准备投这些厂可以吗?
2876
6
...
美团第二次笔试 算法题直接白卷投降
2814
7
...
大疆结构秋招一面
2687
8
...
小红书-引擎架构- java实习-一&二面凉经
2644
9
...
百度提前批一面凉经!继续复习!
2591
10
...
影石嵌入式面经
2473
创作者周榜
更多
正在热议
更多
#
你上一次给父母打电话是什么时候
#
13906次浏览
126人参与
#
扒一扒那些奇葩实习经历
#
71528次浏览
935人参与
#
秋招笔面试记录
#
200525次浏览
3451人参与
#
发工资后,你做的第一件事是什么
#
72696次浏览
252人参与
#
在职场上,你最讨厌什么样的同事
#
28253次浏览
206人参与
#
给26届的秋招建议
#
39875次浏览
1014人参与
#
实习的内耗时刻
#
60280次浏览
642人参与
#
我的秋招“寄”录
#
46133次浏览
602人参与
#
秋招投递记录
#
28510次浏览
315人参与
#
节后第一天上班,我的精神状态
#
13987次浏览
122人参与
#
校招第一份工作你干了多久?
#
99285次浏览
438人参与
#
安克创新求职进展汇总
#
40212次浏览
448人参与
#
我的AI电子员工
#
13465次浏览
107人参与
#
今年秋招哪家公司给的薪资最良心?
#
263054次浏览
1459人参与
#
选offer应该考虑哪些因素
#
86549次浏览
768人参与
#
如果校招重来我最想改变的是
#
279857次浏览
2908人参与
#
你最近一次加班是什么时候?
#
80277次浏览
432人参与
#
秋招,不懂就问
#
12465次浏览
135人参与
#
应届生初入职场,求建议
#
240769次浏览
2718人参与
#
工作上你捅过哪些篓子?
#
22168次浏览
140人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务