Spring基础
Spring:一款开源的轻量级Java开发框架(Spring最核心的思想就是不重新造轮子,开箱即用,提高开发效率)。
一些重要的spring模块:
Spring Core:基础,Spring其他所有的功能都依赖于该类库。主要提供IOC和DI功能。
Spring Aspects:该模块为与AspectJ的集成提供支持。
Spring AOP:提供面向切面的编程实现。
Spring JDBC:Java数据库连接。
Spring JMS:Java消息服务。
Spring ORM:用于支持Hibernate等ORM工具。
Spring Web:为创建Web应用程序提供支持。
Spring Test:提供了对JUnit和TestNG测试的支持。
Core Container
Spring框架的核心模块,也可以说是基础模块,主要提供 IoC 依赖注入功能的支持。Spring 其他所有的功能基本都需要依赖于该模块,我们从上面那张 Spring 各个模块的依赖关系图就可以看出来。
spring-core:Spring 框架基本的核心工具类(主要提供 IoC 依赖注入功能的支持)。
spring-beans:提供对 bean 的创建、配置和管理等功能的支持。
spring-context:提供对国际化、事件传播、资源加载等功能的支持。
spring-expression:提供对表达式语言(Spring Expression Language) SpEL 的支持,只依赖于core模块,不依赖于其他模块,可以单独使用。
# AOP
spring-aspects:该模块为与 AspectJ 的集成提供支持。
spring-aop:提供了面向切面的编程实现。
spring-instrument:提供了为 JVM 添加代理(agent)的功能。
# Data Access/Integration
spring-jdbc :提供了对数据库访问的抽象 JDBC。不同的数据库都有自己独立的 API 用于操作数据库,而 Java 程序只需要和 JDBC API 交互,这样就屏蔽了数据库的影响。
spring-tx :提供对事务的支持。
spring-orm :提供对 Hibernate、JPA 、iBatis 等ORM框架的支持。
spring-oxm :提供一个抽象层支撑OXM(Object-to-XML-Mapping),例如:JAXB、Castor、XMLBeans、JiBX 和 XStream等。
spring-jms : 消息服务。自Spring Framework 4.1 以后,它还提供了对 spring-messaging 模块的继承。
# Spring Web
spring-web :对 Web 功能的实现提供一些最基础的支持。
spring-webmvc : 提供对 Spring MVC 的实现。
spring-websocket : 提供了对 WebSocket 的支持,WebSocket 可以让客户端和服务端进行双向通信。
spring-webflux :提供对 WebFlux 的支持。WebFlux 是 Spring Framework 5.0 中引入的新的响应式框架。与 Spring MVC 不同,它不需要 Servlet API,是完全异步。
# Messaging
spring-messaging 是从 Spring4.0 开始新加入的一个模块,主要职责是为 Spring 框架集成一些基础的报文传送应用。
# Spring Test
Spring 团队提倡测试驱动开发(TDD)。有了控制反转 (IoC)的帮助,单元测试和集成测试变得更简单。
Spring 的测试模块对 JUnit(单元测试框架)、TestNG(类似 JUnit)、Mockito(主要用来 Mock 对象)、PowerMock(解决 Mockito 的问题比如无法模拟 final, static, private 方法)等等常用的测试框架支持的都比较好。
Spring框架中用到了哪些设计模式?
1.工厂设计模式:Spring使用工厂模式通过BeanFactory和ApplicationContext创建bean对象。
2.代理设计模式:Spring AOP功能的实现。
3.单例设计模式:Spring中的bean默认都是单例的。
4.模板方法模式:Spring中的jdbcTemplate、hibernateTemplate等以Template结尾的对数据库操作的类,它们就使用到了模板模式。
5.包装器设计模式:我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
6.观察者模式:Spring事件驱动模型就是观察者模式很经典的一个应用。
7.适配器模式:Spring AOP的增强或通知(Advice)使用到了适配器模式、Spring MVC中也是用到了适配器模式适配Controller。
什么是循环依赖?
BeanA类依赖了BeanB类,同时BeanB类又依赖了BeanA类。这种依赖关系形成了一个闭环,我们把这种依赖关系就称之为循环依赖。
常规情况下,会出现以下情况:
通过构建函数创建A对象(A对象是半成品,还没注入属性和调用init方法)。
A对象需要注入B对象,发现对象池(缓存)里还没有B对象(对象在创建并且注入属性和初始化完成之后,会放入对象缓存里)。
通过构建函数创建B对象(B对象是半成品,还没注入属性和调用init方法)。
B对象需要注入A对象,发现对象池里还没有A对象。
创建A对象,循环以上步骤。
Spring 循环依赖的场景有两种:
构造器的循环依赖。
field 属性的循环依赖。
对于构造器的循环依赖,Spring 是无法解决的,只能抛出 BeanCurrentlyInCreationException 异常表示循环依赖,所以下面我们分析的都是基于 field 属性的循环依赖。
Spring 只解决 scope 为 singleton 的循环依赖。对于scope 为 prototype 的 bean ,Spring 无法解决,直接抛出 BeanCurrentlyInCreationException 异常。
解决循环依赖:
Spring创建Bean的过程中会用到三级缓存:
// DefaultSingletonBeanRegistry.java /** * 一级缓存,存放可用的成品Bean。 * 对应关系为 bean name --> bean instance */ private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); /** * 二级缓存,存放半成品的Bean,半成品的Bean是已创建对象,但是未注入属性和初始化。用以解决循环依赖。 * 对应关系也是 bean name --> bean instance。 */ private final Map<String, Object> earlySingletonObjects = new HashMap<>(16); /** * 三级缓存,存的是Bean工厂对象,用来生成半成品的Bean并放入到二级缓存中。用以解决循环依赖。 * 对应关系是 bean name --> ObjectFactory */ private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
参考链接:
https://blog.csdn.net/tianjindong0804/article/details/124083142
https://www.cnblogs.com/msjhw/p/15648620.html