1.什么是Spring?

spring 接口 非单例_不可重复读

 

Spring是一个轻量级的Java框架,它的使命是解决企业级应用开发的复杂性,简化Java开发

2.Spring的优缺点?

优点:

1.代码解耦  Spring使用IOC对对象进行管理,当需要对象时使用DI(依赖注入),大大减少了代码的耦合

2.AOP的支持  Spring提供面向切面编程,方便的实现对程序进行权限拦截,运行监控等功能

3.支持声明式事务  控制事务只需要通过配置,不需要手动编程

4.方便程序的测试  Spring支持Junit4,可以通过注解方便的测试程序

5.可以整合各种框架  典型的框架像Mybatis,mybatisplus,Hibernate等等

缺点:Spring底层依赖反射,比较消耗性能

3.Spring中用到了哪些设计模式?

  1. 工厂模式:用于对象的创建
  2. 单例模式:Bean默认为单例
  3. 代理模式:SpringAOP使用了JDK动态代理和Cglib动态代理,当被代理类实现了至少一个接口,则会使用jdk动态代理,否则使用的是cglib
  4. 模板方法:解决代码复用。比如RestTemplate,JdbcTemplate等等
  5. 观察者模式:定义了一种对象间的一对多的关系,当一个对象的状态发生改变时,所有依赖它的对象都会得到通知被动更新

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是如何处理并发问题的?

  1. ThreadLocal。ThreadLocal为每一个线程提供了一个副本,隔离了多个线程对共享数据的访问冲突,这是一种空间换时间的做法
  2. 线程同步。通过给共享数据加锁,只有当线程拿到锁后才能对数据进行操作。这是一种时间换空间的做法。

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中有五大事务隔离级别,分别是:

  1. ISOLATION_DEFAULT:用底层数据库的隔离级别,数据库用的啥就是啥
  2. ISOLATION_READ_UNCOMMITTED:未提交读,最低的隔离级别,事务未提交前数据就可被其他事务读取到,会出现脏读,幻读,不可重复读
  3. ISOLATION_READ_COMMITED:已提交读,数据再事务提交后才能被其他事务读取到(避免了脏读,不可避免幻读和不可重复读)
  4. ISOLATION_REPEATABLE_READ:可重复读,它保证一个事务多次读取一个数据时,其值都和事务开始时是一样的,不可避免幻读

     5.ISOLATION_SERIALIZABLE:序列化,最高级别的隔离级别,可以避免脏读,不可重复读,   幻读