Spring中的Bean是线程安全的吗?

Spring 中的 bean 默认都是单例的,所有线程都共享一个单例实例Bean,因此是存在资源的竞争,是线程不安全的

但是spring中大部分bean都是在方法内部操作,例如:Controller、Service、Dao等,不会对bean的成员变量做查询以外的操作,这种bean是线程安全的。如果非要在这些bean中定义成员变量并修改它,可以声明@Scope("prototype")保证线程安全。

在spring内部有一些bean会对成员变量操作,例如:RequestContextHolder等,这种bean一般通过ThreadLocal来解决线程安全的问题。

@Component 和 @Bean 的区别是什么?

  • @Component注解作用于;而@Bean作用于方法
  • @Component一般是用过类路径来自动装配到spring中;@Bean一般是在方法中产生一个bean,然后将这个bean交给spring管理。
  • @Bean注解比@Component注解的自定义性更强,很多时候我们需要将第三方类库中的bean装配到spring中时,只能通过@Bean来实现。

SpringMVC 工作原理

  • 客户端发送请求,到达DispatcherServlet
  • DispatcherServlet根据请求信息调用HandlerMapping
  • HandlerMapping解析请求到对应的Handler(Controller)后,开始由HandlerAdapter来处理。
  • HandlerAdapter根据Handler调用真正的处理器来处理请求。
  • 处理器处理完以后,返回一个ModelAndView对象。
  • ViewResolver根据ModelAndView中的View查找实际的View。
  • DispaterServlet将ModelAndView中的Model传给View。
  • 最后把实际的View返回给请求者。

在Spring容器初始化的过程中,所有定义的bean都会被初始化吗?

不是,默认只初始化所有未初始化的非懒加载的单例Bean,scope为其它值的bean会在使用到的时候进行初始化,如prototype。

Spring如何解决循环依赖?

spring注入属性方式有多种,但是只有一种循环依赖被解决:setter依赖注入。其他的注入方式,Spring也没有办法解决,只是抛出BeanCurrentlyInCreationException异常。

spring解决循环依赖的方式是采用三级缓存,未等bean创建完成之前就先将实例曝光出去,方便其他bean引用。

核心代码

//singletonObjects指单例对象的cache (一级缓存)private final Map singletonObjects = new ConcurrentHashMap(256);//singletonFactories指单例对象工厂的cache(三级缓存)private final Map> singletonFactories = new HashMap>(16);//earlySingletonObjects指提前曝光的单例对象的cache(二级缓存)private final Map earlySingletonObjects = new HashMap(16);
protected Object getSingleton(String beanName, boolean allowEarlyReference) {   //从一级缓存获取   Object singletonObject = this.singletonObjects.get(beanName);   //isSingletonCurrentlyInCreation():判断当前单例bean是否正在创建中   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {      synchronized (this.singletonObjects) {         //从二级缓存获取         singletonObject = this.earlySingletonObjects.get(beanName);         //allowEarlyReference:是否允许从singletonFactories中通过getObject拿到对象         if (singletonObject == null && allowEarlyReference) {            //从三级缓存获取            ObjectFactory> singletonFactory = this.singletonFactories.get(beanName);            if (singletonFactory != null) {               singletonObject = singletonFactory.getObject();               this.earlySingletonObjects.put(beanName, singletonObject);               this.singletonFactories.remove(beanName);            }         }      }   }   return (singletonObject != NULL_OBJECT ? singletonObject : null);}

图解


A首先完成了初始化的第一步,并且将自己提前曝光到singletonFactories中

此时进行初始化的第二步,发现自己依赖对象B,此时就尝试去get(B),发现B还没有被create,所以走create流程,

B在初始化第一步的时候发现自己依赖了对象A,于是尝试get(A),尝试一级缓存singletonObjects(没有,因为A还没初始化完全),尝试二级缓存earlySingletonObjects(也没有),尝试三级缓存singletonFactories,由于A通过ObjectFactory将自己提前曝光了,所以B能够通过ObjectFactory.getObject拿到A对象(此时A还没有初始化完全),

B拿到A对象后顺利完成了初始化阶段1、2、3,完全初始化之后将自己放入到一级缓存singletonObjects中

此时返回A中,A此时能拿到B的对象顺利完成自己的初始化阶段2、3,最终A也完成了初始化,进去了一级缓存singletonObjects中,而此时,由于B拿到了A的对象引用,所以B现在引用的A对象完成了初始化

springboot原理,如何实现的自动装配?

首先看启动类上的@SpringBootApplication注解

@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan(    excludeFilters = {@Filter(    type = FilterType.CUSTOM,    classes = {TypeExcludeFilter.class}), @Filter(    type = FilterType.CUSTOM,    classes = {AutoConfigurationExcludeFilter.class})})public @interface SpringBootApplication {

再看里面的@EnableAutoConfiguration注解

@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@AutoConfigurationPackage@Import({AutoConfigurationImportSelector.class})public @interface EnableAutoConfiguration {

然后通过@Import注入AutoConfigurationImportSelector类,这个类通过实现DeferredImportSelector来重写selectImports方法去加载META-INF/spring.factories这个外部文件,这个外部文件里面,默认有很多自动配置的类,这些类的定义信息将会被SpringBoot批量的注入到spring容器中,从而实现了自动装配。

相关的starter和自定义starter都是根据这个实现的。

spring事务以及传播机制

spring事务是封装在数据库事务之上的一种事务处理机制,它有两种管理方式:编程式事务和声明式事务

spring事务的传播机制有七种:REQUIRED、REQUIRES_NEW、NESTED、SUPPORTS、NOT_SUPPORTED、MANDATORY和NEVER

详细介绍参考以前的文章:传送门

springboot打包成jar之后,怎么做到不重新打包修改他的properties配置文件?

Spring程序会按优先级从下面这些路径来加载application.properties配置文件

  • 当前目录下的/config目录
  • 当前目录
  • classpath里的/config目录
  • classpath 跟目录

因此,要外置配置文件就很简单了,在jar所在目录新建config文件夹,然后放入配置文件,或者直接放在jar同级目录

bootstrap.properties 和 application.properties 有何区别 ?

单纯做 Spring Boot 开发,可能不太容易遇到 bootstrap.properties 配置文件,但是在结合 Spring Cloud 时,这个配置就会经常遇到了。

  • bootstrap (. yml 或者 . properties):boostrap 由父 ApplicationContext 加载的,比 applicaton 优先加载,配置在应用程序上下文的引导阶段生效。一般来说我们在 Spring Cloud 配置就会使用这个文件。且 boostrap 里面的属性不能被覆盖;
  • application (. yml 或者 . properties):由ApplicatonContext 加载,用于 spring boot 项目的自动化配置。

Spring Boot 打成的 jar 和普通的 jar 有什么区别 ?

  • Spring Boot 项目最终打包成的 jar 是可执行 jar ,这种 jar 可以直接通过 java -jar xxx.jar 命令来运行。
  • Spring Boot 的 jar 无法被其他项目依赖,主要还是他和普通 jar 的结构不同。普通的 jar 包,解压后直接就是包名,包里就是我们的代码,而 Spring Boot 打包成的可执行 jar 解压后,在 \BOOT-INF\classes 目录下才是我们的代码,因此无法被直接引用。

扫一扫,关注我


Java面试系列-redis相关

2020-09-29

Java面试系列-线程相关(一)

2020-09-03

Java到底是引用传递还是值传递

2020-08-07

redis分布式锁

2020-06-05

手摸手教你搭建免费图床

2020-05-28

spring cloud每次修改必须重新打包_Java面试系列spring相关相关推荐

  1. spring cloud nacos 配置多环境打包

    spring cloud nacos 配置多环境打包 一.前言 因需要将项目打包给N多第三方,他们有各自的nacos地址,又需要实现代码无侵入(配置文件存在很多版本如 application-tocd ...

  2. Spring Cloud 与 Dubbo 的完美融合之手「Spring Cloud Alibaba」

    很早以前,在刚开始搞 Spring Cloud 基础教程的时候,写过这样一篇文章:<微服务架构的基础框架选择:Spring Cloud 还是 Dubbo ?>,可能不少读者也都看过.之后也 ...

  3. Java 微服务框架选型(Dubbo 和 Spring Cloud?),大厂 HR 如何面试

    写在最前面,我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家.扫码加微信好友进[程序员面试学习交流群],免费领取.也欢迎各位一起在群里探讨技术. 微服 ...

  4. Spring Cloud与微服务学习总结(2)——Spring Cloud相较于Dubbo等RPC服务框架的优势

    摘要: 目前,Spring Cloud在国内的知名度并不高,在前阵子的求职过程中,与一些互联网公司的架构师.技术VP或者CTO在交流时,有些甚至还不知道该项目的存在.可能这也与国内阿里巴巴开源服务治理 ...

  5. 《深入理解 Spring Cloud 与微服务构建》第三章 Spring Cloud

    <深入理解 Spring Cloud 与微服务构建>第三章 Spring Cloud 文章目录 <深入理解 Spring Cloud 与微服务构建>第三章 Spring Clo ...

  6. Spring Cloud与微服务学习总结(9)——Spring Cloud面试题汇总

    为什么需要学习Spring Cloud 不论是商业应用还是用户应用,在业务初期都很简单,我们通常会把它实现为单体结构的应用.但是,随着业务逐渐发展,产品思想会变得越来越复杂,单体结构的应用也会越来越复 ...

  7. Spring Cloud Stream与RabbitMQ整合时Producer与Consumer的相关配置

    生产者属性 下面的属性都必须添加前缀: spring.cloud.stream.<rabbitName>.bindings.<channelName>.producer. 如果 ...

  8. spring cloud全家桶_阿里架构师玩转spring全家桶(实战篇),附赠3本spring电子书...

    Spring框架自诞生以来一直备受开发者青睐,今天在这里分享的是Spring全家桶实战篇电子书籍.书籍内容中包括了Spring.SpringBoot.SpringCloud.SpringMVC四个实战 ...

  9. Spring Cloud与微服务学习总结(1)——Spring Cloud及微服务入门

    一.Spring Cloud是什么鬼?  Spring Cloud为开发者提供了快速建立一些常见的模式在分布式系统的工具(如配置管理.服务发现.断路器.智能路由.微代理,控制总线,一次性令牌,全球锁, ...

最新文章

  1. 9.spark core之共享变量
  2. 用STL给C++充电:第一部分
  3. 决策树算法之ID3与C4.5的理解与实现
  4. JSP四大域对象与九大内置对象
  5. 英语学习笔记2019-10-11
  6. colgroup标签
  7. 洛谷3871 [TJOI2010]中位数 维护队列的中位数
  8. tensorflow之reduce_mean
  9. 【Python实例第14讲】普通判别分析与缩水判别分析
  10. 11. JavaScript 对象
  11. JAVAWeb项目 微型商城项目-------(七)后台添加用户管理和商品类型管理操作
  12. Python文件中,reload(sys)找不到的问题
  13. 编写微信聊天机器人1《聊天精灵WeChatGenius》:搭建环境,创建项目,提交GitHub。
  14. 从jupyter转换为exe格式
  15. 由于找不到 MSVCR120.dll,无法继续执行代码终极解决方法
  16. C#获取中国免费的天气信息
  17. python三阶魔方_三阶魔方自动求解及动态可视化matlab代码
  18. 郭店楚简——原简整理,文物出版社
  19. java中使用集合模拟斗地主发牌的两种排序(根据大小或者花色)
  20. 3纠结的刺:当专家还是管理者

热门文章

  1. LeetCode 100. 相同的树(二叉树遍历)
  2. ai预测占比_2019-2021年中国AI芯片市场预测与展望数据
  3. java mysql geo_GEO数据库简介
  4. Linux查看指定进程占用mem,Linux查看占用mem的进程脚本
  5. jedis连接mysql_使用Jedis操作Redis数据库
  6. ipv6 访问内网_【内网渗透】—— 隐藏通信隧道技术之网络层隧道技术
  7. BERT重计算:用22.5%的训练时间节省5倍的显存开销(附代码)
  8. 前端遇上Go: 静态资源增量更新的新实践
  9. 根因分析初探:一种报警聚类算法在业务系统的落地实施 1
  10. 会议交流—PPT下载|DataFunSummit2022:知识图谱在线峰会PPT合集!