1. Spring是什么?
一个轻量级的IoC和AOP容器框架,目的是用于简化企业应用程序的开发
2. Spring 的优点?
- 属于低侵入式设计,代码的污染极低
- DI机制将对象之间的依赖关系交由框架处理,减低组件的耦合性
- Spring提供了AOP技术,支持将一些通用任务,如安全、事务、日志、权限等进行集中式管理,从而提供更好的复用
- spring对于主流的应用框架提供了集成支持
3. 什么是IOC?
- IOC:控制反转,指将对象的控制权转移给Spring框架,由 Spring 来负责控制对象的生命周期和对象间的依赖关系
- 对于某个具体的对象而言,以前是由自己控制它所引用对象的生命周期,而在IOC中,所有的对象都被 Spring 控制,控制对象生命周期的不再是引用它的对象,而是Spring容器,由 Spring 容器帮我们创建、查找及注入依赖对象,而引用对象只是被动的接受依赖对象,所以这叫控制反转。
- Spring 的 IoC 的实现原理就是工厂模式+反射机制
- DI:应用程序在运行时依赖 IoC 容器来动态注入对象所需要的外部依赖。而 Spring 的 DI 具体就是通过反射实现注入的,反射允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性
4. 什么是AOP?
- AOP,一般称为面向切面,作为面向对象的一种补充,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块
- 可用于权限认证、日志、事务处理。
- 关键在于代理模式
- Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。
- JDK动态代理只提供接口的代理,不支持类的代理,要求被代理类实现接口
- 如果被代理类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类
- 静态代理与动态代理区别在于生成AOP代理对象的时机不同,相对来说AspectJ(运行时增强)的静态代理方式具有更好的性能,但是AspectJ需要特定的编译器进行处理,而Spring AOP则无需特定的编译器处理。
5. Spring AOP里面的几个名词
- 连接点(Join point)
- 切面(Aspect)
- 切点(Pointcut)
- 通知(Advice)
- 目标对象(Target)
- 织入(Weaving)
- 引入(Introduction)
6. Spring Bean的生命周期?
简单来说,Spring Bean的生命周期只有四个阶段:实例化 Instantiation –> 属性赋值 Populate –> 初始化 Initialization –> 销毁 Destruction
详细来说:
- 实例化Bean
- 设置对象属性(依赖注入)
- 处理Aware接口
- BeanPostProcessor前置处理
- InitializingBean
- init-method
- BeanPostProcessor后置处理
- DisposableBean
- destroy-method
7. Spring中bean的作用域
- singleton:默认作用域,单例bean,每个容器中只有一个bean的实例
- prototype:为每一个bean请求创建一个实例
- request:为每一个request请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。
- session:与request范围类似,同一个session会话共享一个实例,不同会话使用不同的实例
- global-session:全局作用域,所有会话共享一个实例。如果想要声明让所有会话共享的存储变量的话,那么这全局变量需要存储在global-session中。
8. Spring框架中的Bean是线程安全的么?如果线程不安全,那么如何处理?
Spring容器中的Bean本身不具备线程安全的特性
- 对于prototype作用域的Bean,每次都创建一个新对象,也就是线程之间不存在Bean共享,因此不会有线程安全问题。
- 对于singleton作用域的Bean,所有的线程都共享一个单例实例的Bean,因此是存在线程安全问题的,
有状态Bean(Stateful Bean) :就是有实例变量的对象,可以保存数据,是非线程安全的。
无状态Bean(Stateless Bean):就是没有实例变量的对象,不能保存数据,是不变类,是线程安全的。
- 解决办法1:将有状态的bean的作用域由“singleton”改为“prototype”。
- 解决办法2:可以采用ThreadLocal解决线程安全问题,为每个线程提供一个独立的变量副本
9. Spring基于xml注入bean的几种方式
- set()方法注入;
- 构造器注入:①通过index设置参数的位置;②通过type设置参数类型;
- 静态工厂注入;
- 实例工厂;
10. Spring如何解决循环依赖问题?
三种情况
- 通过构造方法进行依赖注入时产生的循环依赖问题(new对象的时候就会堵塞住了)
- 通过setter方法进行依赖注入且是在多例(原型)模式下产生的循环依赖问题(每一次getBean()时,都会产生一个新的Bean,如此反复下去就会有无穷无尽的Bean产生了)
- 通过setter方法进行依赖注入且是在单例模式下产生的循环依赖问题(已解决)
Spring在单例模式下的setter方法依赖注入引起的循环依赖问题,主要是通过二级缓存和三级缓存来解决的,其中三级缓存是主要功臣。解决的核心原理就是:在对象实例化之后,依赖注入之前,Spring 提前暴露的Bean实例的引用在第三级缓存中进行存储。
11. Spring的自动装配?
- 使用autowire来配置自动装载模式
- 有5种自动装配
- no:默认的方式是不进行自动装配的
- byName:通过bean的名称进行自动装配
- byType:通过参数的数据类型进行自动装配
- constructor:利用构造函数进行装配,并且构造函数的参数通过byType进行装配
- autodetect:自动探测,如果有构造方法,通过 construct的方式自动装配,否则使用 byType的方式自动装配
- @Autowired默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)
- @Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入。
12. Spring事务的实现方式和实现原理
- Spring事务的本质其实就是数据库对事务的支持
- Spring 只提供统一事务管理接口,具体实现都是由各数据库自己实现
- 数据库事务的提交和回滚是通过 redo log 和 undo log实现的。
- Spring会在事务开始时,根据当前环境中设置的隔离级别,调整数据库隔离级别,由此保持一致。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/65610.html