1.spring是如何简化开发的?
- 基于POJO的轻量级和最小侵入编程;
- 通过依赖注入和面向接口实现松耦合;
- 基于切面(AOP)和惯例进行声明式编程;
- 通过切面和模板减少样式代码,RedisTemplate,xxxTemplate。
1.1 基于POJO的轻量级和最小侵入编程(IOC控制反转)
POJO可以理解为Bean对象,那么什么是Bean对象?javaBean是一种由java语言编写的可重用组件,类必须是具体和公共的,并且有无参构造器,通俗来讲:
- 所有类必须被放在一个包中,
- 类必须被声明为public,这样才能够被外部访问,
- 类中的所有属性必须封装(使用private声明),
- 封装的属性如果要被外部操作,必须要通过getter与setter方法,
- 一个JavaBean中至少存在一个无参构造函数
而当我们使用spring进行开发时,就是将bean交给spring容器进行管理,而不需任何干预。
最小侵入式编程就是在编写代码时,整个spring框架不会对我们产生任何局限。
1.2 通过依赖注入和面向接口实现松耦合(IOC控制反转)
依赖注入
以前在创建对象时,需要给对象属性进行赋值操作,无论是通过构造方法还是set方法,而现在交给容器管理之后,会通过DI(依赖注入)的方式替我们完成这个赋值操作;(IOC是实现思想,DI是实现方式)
面向接口
面向接口可以轻松的实现业务扩展
1.3 基于切面(AOP)和惯例进行声明式编程(背过)
声明式事务
声明式事务会帮助我们自动控制事务的回滚和提交
1.4 通过切面和模板减少样式代码(AOP面向切面)
当需要做一些与业务无关的公共功能时,比如记录日志,事务管理,可以通过AOP的方式,将关键的核心代码切入到业务逻辑中去,而不需要去修改每一行代码。
2.对spring的理解?
spring是一个开源框架,一个容器,还是一个生态,spring是一个最底层的服务支持,为spring全家桶提供了支撑,起到了基石的作用
3.spring的核心?
spring是一个开源框架,为了简化企业开发而生,使得开发更加简洁,spring也是一个IOC和AOP的容器框架,包含并管理对象的声明周期,spring容器中通过一些列的map结构进行存储。
4.spring的事务传播机制
4.1 spring对事务的支持
事务在逻辑上是一组操作,要么执行,要不都不执行。spring支持2种事务,分别是编程式事务与声明式事务。
编程式事务是指将事务管理代码嵌入嵌入到业务代码中,来控制事务的提交和回滚。编程式事务管理的粒度可以精确到代码块级别。
声明式事务将事务管理代码从业务方法中抽离了出来,以声明式的方式来实现事务管理,更容易更好用,但是对事务的管理粒度是方法级别。
4.2 spring事务传播机制
当事务方法被另外一个事务方法调用时,必须指定事务应该如何传播。共有7种事务传播行为,其中常用的有2种:PROPAGATION_REQUIRED(默认事务传播机制)和PROPAGATION_REQUIRES_NEW 。
- PROPAGATION_REQUIRED:当使用REQUIRED 时,方法b会加入到当前存在的事务中,如果当前没有事务则b开启一个新的事务
例如在a()中调用b(),会首先判断a()上有没有事务,如果a()是事务方法,b()就用a里边的事务即可,也就是b()方法会加入a的事务,无论a还是b发生异常,都会导致整个事务回滚;
class A{@Transactionalpublic void a(){System.out.println("执行方法a()");b();}@Transactional(propagation = Propagation.REQUIRED)public void b(){System.out.println("执行方法b()");}
}
如果a()不是事务方法,b()自己新建一个事务,此时仅当b方法发生异常时事务回滚,且仅仅b的事务回滚,a不受影响。
class A{public void a(){System.out.println("执行方法a()");b();}@Transactional(propagation = Propagation.REQUIRED)public void b(){System.out.println("执行方法b()");}
}
- PROPAGATION_REQUIRES_NEW:当使用REQUIRES_NEW时,无论当前事务是否存在,方法b()都将启动一个新事务,这意味着2个事务是相互独立的。
无论a()是否是事务方法,b()都会自己新建一个事务,即使a中的事务回滚,b中的事务仍然可以提交。
class A{//@Transactionalpublic void a(){System.out.println("执行方法a()");b();}@Transactional(propagation = Propagation.REQUIRES_NEW)public void b(){System.out.println("执行方法b()");}
}
5.spring框架中单例Bean是线程安全的吗?
不是,Spring框架中的单例bean不是线程安全的。spring 中的 bean 默认是单例模式,spring 框架并没有对单例 bean 进行多线程的封装处理。实际上大部分时候 spring bean 无状态的(比如 dao 类),所以某种程度上来说 bean 也是安全的,但如果 bean 有状态的话(比如 view model 对象),那就要开发者自己去保证线程安全了。最简单的就是改变 bean 的作用域,把“singleton”变更为“prototype”,这样请求 bean 相当于 new Bean()了,所以就可以保证线程安全了。
多线程场景下,多个线程对这个单例Bean的成员变量并不存在资源的竞争,因为ThreadLocal为每个线程保存线程私有的数据。这是一种以空间换时间的方式。
也可以通过加锁的方法来解决线程安全,这种以时间换空间的场景在高并发场景下显然是不实际的。
- 有状态就是有数据存储功能(比如成员变量读写)。
- 无状态就是不会保存数据。