定义:基于JavaEE的轻量级框架,使用spring可以降低模块的耦合度,提高开发效率。
spring的两大核心(IOC和AOP)
IOC(控制反转)
定义:将传统上由程序代码直接操控的对象调用权交给容器(如Spring框架),通过容器来实现对象的装配和管理。
重点★★★
注入:
1.手动注入
Set注入:指明工厂对象
静态工厂:在配置文件中指明工厂对象并设置对应的方法
实例化工厂:在配置文件中指明工厂对象和工厂方法
2.自动注入
在xml开启自动注入
需要@Autowired、@Resource等注解来注入
在javabean对象上面添加注解
AOP(面向切面编程)
定义:一种在软件开发中用于降低业务逻辑各部分之间耦合度的技术,通过预编译方式和运行期间动态代理实现程序功能的统一维护。
重点★★★
代理模式(静态代理和动态代理)
静态代理:代理模式是在不修改目标对象(被代理对象)的基础上,通过代理对象(扩展代理类),进行一些功能的附加与增强。
特点:
1. 目标对象固定
2. 在程序运行前已经得到目标对象
3. 对目标对象进行增强
缺点:当需要大量代理类是,可能会产生"类爆炸"
动态代理:允许在运行时动态地创建一个实现了一组接口的代理类。与静态代理不同,动态代理不需要手动为每个接口编写代理类。相反,它使用了一个称为InvocationHandler
的接口和一个Proxy
类来动态地生成代理对象。
特点:
JDK动态代理与CGLIB动态代理区别
常见面试题
1、Bean对象的循环依赖问题是什么,怎么解决。
循环依赖是二个或者三个bean对象相互依赖造成的问题。
解决:
-
构造器注入:这种方式是将依赖对象作为构造函数的参数传入,这要求在构造对象的时候必须提供所有的依赖。但是,当存在循环依赖的时候,这种方法会失败,因为每个对象在构造的时候都要求其依赖已经构造完成。Spring框架通过一种名为"三级缓存"的技术来解决这个问题。在创建对象的过程中,Spring会在缓存中查找是否已经创建了该对象的实例。如果找到了,就直接使用,否则就创建一个新的实例。
-
setter注入:这种方式是通过setter方法或者注解将依赖注入到对象中。这种方式允许对象在构造后,再完成依赖的注入,这也使得循环依赖成为可能。Spring框架通过"三级缓存"来解决这个问题。在创建对象的过程中,Spring会在缓存中查找是否已经创建了该对象的实例。如果找到了,就直接使用,否则就创建一个新的实例。
-
使用三级缓存:在Spring中,可以通过三级缓存解决循环依赖问题。当出现循环依赖问题时,Spring会将Bean放入缓存中,然后通过ObjectFactory提前暴露Bean实例,从而解决循环依赖问题。
2、AOP的运用场景有哪些,如果让你去模拟一个怎么进行实现
日志记录,事务管理,安全性检查,性能监控,异常处理,缓存管理。
以日志为例:
- 导入依赖: 创建在pom.xml导入aop依赖
- 定义切面:创建一个Java类作为切面,并定义所需的切点、通知等。
- 配置切面:使用Spring框架的XML配置或注解方式,将切面与需要被增强的目标类进行关联。
- 编写通知:根据业务需求,编写前置通知、后置通知、环绕通知或异常通知等。
- 运行测试:编写测试用例,运行程序并观察AOP的效果。
3、Spring事务回滚流程
-
异常触发:当事务中的操作抛出运行时异常(如
RuntimeException
)或错误(Error
)时,会触发事务回滚。 -
判断是否需要回滚:Spring会检查事务的配置和异常类型,以确定是否需要执行回滚操作。默认情况下,只有运行时异常和错误会导致回滚。
-
执行回滚:如果确定需要回滚,Spring会调用事务管理器的
rollback
方法,开始执行回滚操作。这通常涉及撤销在事务中进行的所有数据库更改,以恢复到事务开始时的状态。 -
清理资源:在回滚完成后,Spring会释放与事务相关的所有资源,如数据库连接、锁等。
-
通知监听器:如果配置了事务监听器,Spring会在回滚操作完成后通知它们,以便进行后续处理或记录日志等操作。
4、什么情况下事务会失效
1.方法非public修饰
2.方法被final修饰
3.方法内部调用
(如果一个事务方法内部调用了另一个事务方法,并且这种调用是通过this
关键字进行的(即非代理对象调用),那么内部调用的事务方法将不会运行在事务上下文中,因为Spring的AOP代理只能拦截通过外部调用进来的方法。)
4.异常未被抛出或捕获:
Spring默认只对运行时异常(RuntimeException)和Error进行事务回滚。如果方法抛出了检查型异常(Exception),并且没有指定@Transactional的rollbackFor属性来包含该异常类型,那么事务将不会回滚。
5.事务传播行为设置不当:
通过@Transactional的propagation属性可以设置事务的传播行为。如果设置为Propagation.NOT_SUPPORTED或Propagation.NEVER,则当前方法将不会运行在事务上下文中。
6.数据源未配置事务管理器:
如果Spring配置文件中没有为数据源配置相应的事务管理器,或者事务管理器没有正确配置,那么事务将无法正常工作。
7.事务管理器配置错误:
如果有多个数据源,但配置的事务管理器与当前操作的数据源不匹配,那么事务将不会生效。
8.代理模式问题:
Spring提供了两种代理模式:基于接口的JDK动态代理和基于类的CGLIB代理。如果类没有实现接口,并且使用了基于接口的代理模式,那么事务将不会生效。
9.多线程调用:
Spring的事务是通过ThreadLocal与线程绑定的,如果在多线程环境下,一个事务方法被另一个线程调用,那么原线程的事务上下文将无法传递给新线程,导致事务失效。
10.事务被错误地手动控制:
在代码中手动调用Connection.commit()或Connection.rollback()可能会破坏Spring事务管理器的控制,导致事务失效或行为不符合预期。
11.AOP配置问题:
如果Spring AOP配置不正确,或者没有启用AOP代理(如@EnableTransactionManagement注解未添加),那么事务代理将无法生效。
12.Spring版本兼容性问题:
有时,不同版本的Spring框架或相关依赖库之间可能存在兼容性问题,这可能导致事务无法正常工作。
★★★记三、四个即可
5、一二三级缓存分别存储什么信息
一级(singletonObjects
):存储已经完成初始化的单例bean对象
二级(earlySingletonObjects
):存储已经实例化但尚未完成初始化的单例dean对象
三级(ingletonFactories
):存储bean对象的创建工厂
6、详细的日志信息怎么去得到
步骤一,导入所需的Java日志库
步骤二,创建一个文件对象
步骤三,检查文件是否存在
步骤四,读取文件内容
步骤五,解析日志信息