1.什么是Spring?
Spring是一个轻量级的Java框架,它的使命是解决企业级应用开发的复杂性,简化Java开发
2.Spring的优缺点?
优点:
1.代码解耦 Spring使用IOC对对象进行管理,当需要对象时使用DI(依赖注入),大大减少了代码的耦合
2.AOP的支持 Spring提供面向切面编程,方便的实现对程序进行权限拦截,运行监控等功能
3.支持声明式事务 控制事务只需要通过配置,不需要手动编程
4.方便程序的测试 Spring支持Junit4,可以通过注解方便的测试程序
5.可以整合各种框架 典型的框架像Mybatis,mybatisplus,Hibernate等等
缺点:Spring底层依赖反射,比较消耗性能
3.Spring中用到了哪些设计模式?
- 工厂模式:用于对象的创建
- 单例模式:Bean默认为单例
- 代理模式:SpringAOP使用了JDK动态代理和Cglib动态代理,当被代理类实现了至少一个接口,则会使用jdk动态代理,否则使用的是cglib
- 模板方法:解决代码复用。比如RestTemplate,JdbcTemplate等等
- 观察者模式:定义了一种对象间的一对多的关系,当一个对象的状态发生改变时,所有依赖它的对象都会得到通知被动更新
4.Spring应用程序有哪些组件?
Bean:实体类,包含属性,get,set方法,函数
接口:定义功能
用户程序:实现接口的功能
Xml配置文件:用于配置和管理类
AOP:提供切面函数
5.BeanFactory和ApplicationContext有什么区别?
两者都可以当做Spring的容器,ApplicationContext是BeanFactory的子接口。BeanFactory能够读取Bean的配置,管理Bean的生命周期,维护Bean的依赖关系
ApplicationContext接口是BeanFactory的派生,不仅有BeanFactory提供的功能,还提供了更完整的框架功能。他们的加载方式略有不同。
BeanFactory采用延迟加载的方式注入bean,即只有在用到某个bean的时候才对该bean进行实例化。这种方式节省了内存空间,但是也存在隐患,就是我们不能及时发现bean的配置存在的问题,只有当用到这个bean的时候才能发现。
ApplicationContext在容器启动时就把所有bean都加载好了,避免了上述问题,而且在我们需要bean的时候能够直接拿到,但是这样的方式也使得它占用内存空间较多,造成不必要的浪费。
6.怎样定义类的作用域?
它可以通过bean的scope属性来定义
作用域分为以下五种:
Singleton(默认):bean在容器中只有一个实例
Prototype:一个bean可以有多个实例
Request:每次http请求都会创建一个bean实例
Session:在一个httpSession中,一个session对应一个实例
Global-session:在一个全局的http session中,一个bean定义对应一个实例
7.Spring中bean是线程安全的吗?
不是,Spring并未对bean进行线程安全的处理,因为bean多数情况下是无状态的(没有数据存储功能),所以也不存在线程安全问题,但是如果是类似ModelAndView这样的有状态对象,那么就需要自己去保证线程的安全,此时可以把类的作用域改为prototype。
8.Spring是如何处理并发问题的?
- ThreadLocal。ThreadLocal为每一个线程提供了一个副本,隔离了多个线程对共享数据的访问冲突,这是一种空间换时间的做法
- 线程同步。通过给共享数据加锁,只有当线程拿到锁后才能对数据进行操作。这是一种时间换空间的做法。
9.什么是内部bean?
当一个bean作为另一个bean的属性时,它能被声明为一个内部bean,他可以和其他属性一样通过setter注入,或者通过构造方法注入,它的scope一般是prototype
10.@Autowired和@Resource的区别?
Autowired按照类型装配,默认情况下它要求依赖的对象必须存在(可以设置required = false),按照类型装配有一点问题,如果我们有多个bean类型相同,那么应该注入哪一个呢?此时就用到了@Qualifier注解,它通过和autowired配合来确定装配哪一个bean。
Resource按照名称来装配,只有当找不到名称与之匹配的bean时才按照类型装配
11.Spring的事务隔离级别?
脏读:一个事务能读取另一个事务未提交的数据。假设事务A对数据进行了修改但未提交,事务B读取数据,此时事务A又进行了回滚,那么事务B读取的数据就是脏数据。
不可重复读:在同一次事务中两次读取的数据值不一样。事务A第一次查询到age为10,然后进行别的操作,此时事务B对age进行了修改为20并提交。事务A再次查询age得到20
幻读:同一个事务多次查询到的结果集不一致。事务A第一次对所有行数据进行了修改并提交,事务B又插入了一条数据并提交,此时事务A再次查询结果集会发现多了一条数据,就像发生了幻觉,这就是幻读。
幻读和不可重复读看起来非常相似,幻读侧重于数据的插入和删除,偏向数据量的变化,而不可重复读侧重于数据值的变化。
Spring中有五大事务隔离级别,分别是:
- ISOLATION_DEFAULT:用底层数据库的隔离级别,数据库用的啥就是啥
- ISOLATION_READ_UNCOMMITTED:未提交读,最低的隔离级别,事务未提交前数据就可被其他事务读取到,会出现脏读,幻读,不可重复读
- ISOLATION_READ_COMMITED:已提交读,数据再事务提交后才能被其他事务读取到(避免了脏读,不可避免幻读和不可重复读)
- ISOLATION_REPEATABLE_READ:可重复读,它保证一个事务多次读取一个数据时,其值都和事务开始时是一样的,不可避免幻读
5.ISOLATION_SERIALIZABLE:序列化,最高级别的隔离级别,可以避免脏读,不可重复读, 幻读