Java # Spring(2)

一、Spring事物

一、分类

编程式事物:代码中硬编码(不推荐使用)

声明式事物:配置文件中配置(推荐使用)

  • 分类:
    • 基于xml的声明式事物
    • 基于注解的声明式事物

二、隔离级别

  • ISOLATION_DEFAULT:使用后端数据库默认的隔离级别
    • Mysql默认采用的REPEATABLE_READ隔离级别
    • Oracle默认采用的READ_COMMITTED隔离级别
  • ISOLATION_READ_UNCOMMITTED:最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
  • ISOLATION_READ_COMMITTED:允许读取并发事物已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
  • ISOLATION_REPEATABLE_READ:对同一字段的多次读取结果都是一致的,除非数据是被本身事物自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
  • ISOLATION_SERIALIZABLE:最高的隔离级别,完全服从ACID的隔离级别,串行化。

三、事物传播行为

一、支持当前事物的情况

  1. TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
  2. TransactionDefinition.PROPAGATION_SUPPORTS: 如果当前存在事务,则加入该事务:如果当前没有事务,则以非事务的方式继续运行。
  3. Transaction Definition.PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务:如果当前没有事务,则抛出异常。(mandatory:强制性)

二、不支持当前事物的情况

  1. TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事物,如果当前存在事物,则把当前事物挂起。
  2. TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事物方式运行,如果当前存在事物,则抛出异常。
  3. TransactionDefinition.PROPAGATION_NEVER:以非事物方式运行,如果当前存在事物,则抛出异常。

三、其他情况

TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事物的嵌套事务来运行;如果当前没有事物,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED

四、设计模式

  • 工厂设计模式:Spring使用工厂模式通过BeanFactory、ApplicationContext创建Bean对象。
  • 代理设计模式:Spring AOP功能的实现。
  • 单例设计模式:Spring中的Bean默认都是单例的。
  • 模版方法模式:Spring中jdbcTemplate、hibernateTemplate等以Template结尾的对数据库操作的类,它们就使用到了模版模式。
  • 包装器设计模式:我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
  • 观察者模式:Spring事件驱动模型就是观察者模式很经典的一个应用。
  • 适配器模式:Spring AOP的增强或通知(Advice)使用到了适配器模式、spring MVC中也是用到类适配器模式适配Controller。

五、Spring MVC

一、概述

Model1时代存在的问题:

  • 将控制逻辑和表现逻辑混杂在一起,导致代码重用率极低。
  • 前端和后端相互依赖,难以进行测试并且开发效率极低。

Model2时代存在的问题:

  • 抽象和封装程度远远不够。
  • 重复造轮子,降低了程序的可维护性和复用性。

MVC是一种设计模式,Spring MVC一款很优秀的MVC框架,天生与Spring框架集成。

Spring MVC下我们一般把后端项目分为Service层(处理业务)、Dao层(数据库操作)、Entity层(实体类)、Controller层(控制层,返回数据给前台页面)

二、工作原理 

Java # Spring(2)_第1张图片

六、Spring bean

一、作用域

  • singleton:唯一bean实例,Spring中的bean默认都是单例的。
  • prototype:每次请求都会创建一个新的bean实例。
  • request:每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。
  • session:每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP session内有效。
  • global-session:全局session作用域,仅仅在基于portlet的web应用中才有意义,Spring5已经没有了。

二、单例bean线程安全

        多个线程操作同一个对象的时候,对这个对象的成员变量的写操作会存在线程安全问题。一般情况下,我们常用的Controller,Service,Dao这些Bean是无状态的。无状态的Bean不能保存数据,因此线程是安全的。

解决方法:

  • 在类中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在ThreadLocal中(推荐的一种方式)。
  • 改变Bean的作用域为“prototype”:每次请求都会创建一个新的bean实例,自然不会存在线程安全问题。

三、@Component和@Bean的区别

  • @Component:注解作用于类,通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中(我们可以使用@ComponentScan注解定义要扫描的路径从中找出标识了需要装配的类自动装配到Spring的bean容器中)。
  • @Bean:作用于方法,在标有该注解的方法中定义产生这个bean,@Bean告诉了Spring这是某个类的示例,当我们需要用它的时候还给我。

@Bean注解比@Component注解更强,而且很多地方我们只能通过@Bean注解来注册bean。比如当引用第三方库中的类需要装配到Spring容器时,则只能通过@Bean来实现。

四、类声明为Spring的bean的注解

  • @Autowired注解自动装配bean
  • @Component:通用的注解,可标注任意类为Spring组件。如果一个Bean不知道属于哪个层,可以使用@Component注解标注。
  • @Repository:对应持久层即Dao层,主要用于数据库相关操作。
  • @Service:对应服务层,主要涉及一些复杂的逻辑,需要用到Dao层。
  • @Controller:对应Spring MVC控制层,主要用于接受用户请求并调用Service层返回数据给前端页面。

你可能感兴趣的:(java,八股文,开发语言)