Spring 面试集

基于Spring Framework 4.x 总结的常见面试题,零碎学习倡议还是官网文档走起:https://spring.io/projects/spring-framework#learn

一、个别问题

开发中次要应用 Spring 的什么技术 ?

  1. IOC 容器治理各层的组件
  2. 应用 AOP 配置申明式事务
  3. 整合其余框架

Spring有哪些长处?

  • 轻量级:Spring在大小和透明性方面相对属于轻量级的,根底版本的Spring框架大概只有2MB。
  • 管制反转(IOC):Spring应用管制反转技术实现了松耦合。依赖被注入到对象,而不是创立或寻找依赖对象。
  • 面向切面编程(AOP):Spring反对面向切面编程,同时把利用的业务逻辑与零碎的服务拆散开来。
  • 容器:Spring蕴含并管理应用程序对象的配置及生命周期。
  • MVC框架:Spring的web框架是一个设计低劣的web MVC框架,很好的取代了一些web框架。
  • 事务管理:Spring对下至本地业务上至全局业务(JAT)提供了对立的事务管理接口。
  • 异样解决:Spring提供一个不便的API将特定技术的异样(由JDBC, Hibernate, 或JDO抛出)转化为统一的、Unchecked异样。

Spring模块

简述 AOP 和 IOC 概念

AOP:Aspect Oriented Program, 面向(方面)切面的编程;Filter(过滤器)也是一种 AOP. AOP 是一种新的 方法论, 是对传统 OOP(Object-OrientedProgramming, 面向对象编程) 的补充. AOP 的次要编程对象是切面(aspect),而切面模块化横切关注点.能够举例通过事务阐明.

IOC:Invert Of Control, 管制反转. 也称为 DI(依赖注入)其思维是反转资源获取的方向. 传统的资源查找形式要求组件向容器发动申请查找资源.作为回应, 容器适时的返回资源. 而利用了 IOC 之后, 则是容器被动地将资源推送给它所治理的组件,组件所要做的仅是抉择一种适合的形式来承受资源. 这种行为也被称为查找的被动模式

二、依赖注入

IoC(Inverse of Control:管制反转)是一种设计思维,就是 将本来在程序中手动创建对象的控制权,交由Spring框架来治理。 IoC 在其余语言中也有利用,并非 Spring 特有。 IoC 容器是 Spring 用来实现 IoC 的载体, IoC 容器实际上就是个Map(key,value),Map 中寄存的是各种对象。

将对象之间的相互依赖关系交给 IoC 容器来治理,并由 IoC 容器实现对象的注入。这样能够很大水平上简化利用的开发,把利用从简单的依赖关系中解放出来。 IoC 容器就像是一个工厂一样,当咱们须要创立一个对象的时候,只须要配置好配置文件/注解即可,齐全不必思考对象是如何被创立进去的。 在理论我的项目中一个 Service 类可能有几百甚至上千个类作为它的底层,如果咱们须要实例化这个 Service,你可能要每次都要搞清这个 Service 所有底层类的构造函数,这可能会把人逼疯。如果利用 IoC 的话,你只须要配置好,而后在须要的中央援用就行了,这大大增加了我的项目的可维护性且升高了开发难度。

什么是 Spring IOC 容器?

Spring 框架的外围是 Spring 容器。容器创建对象,将它们拆卸在一起,配置它们并治理它们的残缺生命周期。Spring 容器应用依赖注入来治理组成应用程序的组件。容器通过读取提供的配置元数据来接管对象进行实例化,配置和组装的指令。该元数据能够通过 XML,Java 注解或 Java 代码提供。

什么是依赖注入?

依赖注入(DI,Dependency Injection)是在编译阶段尚未知所需的性能是来自哪个的类的状况下,将其余对象所依赖的性能对象实例化的模式。这就须要一种机制用来激活相应的组件以提供特定的性能,所以依赖注入是管制反转的根底。否则如果在组件不受框架管制的状况下,框架又怎么晓得要创立哪个组件?

依赖注入有以下三种实现形式:

  1. 结构器注入
  2. Setter办法注入(属性注入)
  3. 接口注入

Spring 中有多少种 IOC 容器?

在 Spring IOC 容器读取 Bean 配置创立 Bean 实例之前,必须对它进行实例化。只有在容器实例化后, 才能够从 IOC 容器里获取 Bean 实例并应用

Spring 提供了两种类型的 IOC 容器实现

  • BeanFactory:IOC 容器的根本实现
  • ApplicationContext:提供了更多的高级个性,是 BeanFactory 的子接口

BeanFactory 是 Spring 框架的基础设施,面向 Spring 自身;ApplicationContext 面向应用 Spring 框架的开发者,简直所有的利用场合都间接应用 ApplicationContext 而非底层的 BeanFactory;

无论应用何种形式, 配置文件是雷同的。

BeanFactory 和 ApplicationContext 区别

BeanFactoryApplicationContext
懒加载即时加载
它应用语法显式提供资源对象它本人创立和治理资源对象
不反对国际化反对国际化
不反对基于依赖的注解反对基于依赖的注解

ApplicationContext

ApplicationContext 的次要实现类:

  • ClassPathXmlApplicationContext:从类门路下加载配置文件
  • FileSystemXmlApplicationContext: 从文件系统中加载配置文件
  • ConfigurableApplicationContext 扩大于 ApplicationContext,新减少两个次要办法:refresh() 和 close(), 让 ApplicationContext具备启动、刷新和敞开上下文的能力
  • WebApplicationContext 是专门为 WEB 利用而筹备的,它容许从绝对于 WEB 根目录的门路中实现初始化工作
  • ApplicationContext 在初始化上下文时就实例化所有单例的 Bean

从 IOC 容器中获取 Bean

  • 调用 ApplicationContext 的 getBean() 办法
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");HelloWorld helloWorld = (HelloWorld) ctx.getBean("helloWorld");helloWorld.hello();

列举 IoC 的一些益处

  • 它将最小化应用程序中的代码量;
  • 它将使您的应用程序易于测试,因为它不须要单元测试用例中的任何单例或 JNDI 查找机制;
  • 它以最小的影响和起码的侵入机制促成松耦合;
  • 它反对即时的实例化和提早加载服务

Spring IoC 的实现机制

Spring 中的 IoC 的实现原理就是工厂模式加反射机制,示例:

interface Fruit {     public abstract void eat();}class Apple implements Fruit {    public void eat(){        System.out.println("Apple");    }}class Orange implements Fruit {    public void eat(){        System.out.println("Orange");    }}class Factory {    public static Fruit getInstance(String ClassName) {        Fruit f=null;        try {            f=(Fruit)Class.forName(ClassName).newInstance();        } catch (Exception e) {            e.printStackTrace();        }        return f;    }}class Client {    public static void main(String[] a) {        Fruit f=Factory.getInstance("priv.starfish.spring.Apple");        if(f!=null){            f.eat();        }    }}

三、Beans

什么是 Spring Beans?

  • 它们是形成用户应用程序骨干的对象
  • Bean 由 Spring IoC 容器治理
  • 它们由 Spring IoC 容器实例化,配置,拆卸和治理
  • Bean 是基于用户提供给容器的配置元数据创立

Spring 提供了哪些配置形式?

  • 基于 xml 配置

    bean 所需的依赖项和服务在 XML 格局的配置文件中指定。这些配置文件通常蕴含许多 bean 定义和特定于应用程序的配置选项。它们通常以 bean 标签结尾。例如:

    <bean id="studentbean" class="org.edureka.firstSpring.StudentBean"> <property name="name" value="Edureka"></property></bean>
  • 基于注解配置

    您能够通过在相干的类,办法或字段申明上应用注解,将 bean 配置为组件类自身,而不是应用 XML 来形容 bean 拆卸。默认状况下,Spring 容器中未关上注解拆卸。因而,您须要在应用它之前在 Spring 配置文件中启用它。例如:

    <beans><context:annotation-config/><!-- bean definitions go here --></beans>
  • 基于 Java API 配置

    Spring 的 Java 配置是通过应用 @Bean 和 @Configuration 来实现。

    1. @Bean 注解表演与 <bean/> 元素雷同的角色。

      1. @Configuration 类容许通过简略地调用同一个类中的其余 @Bean 办法来定义 bean 间依赖关系。

例如:

@Configurationpublic class StudentConfig {    @Bean    public StudentBean myStudent() {        return new StudentBean();    }}

Spring Bean的作用域?

  • 在 Spring 中, 能够在 \<bean> 元素的 scope 属性里设置 Bean 的作用域。
  • 默认状况下,Spring 只为每个在 IOC 容器里申明的 Bean 创立惟一一个实例,整个 IOC 容器范畴内都能共享该实例:所有后续的 getBean() 调用和 Bean 援用都将返回这个惟一的 Bean 实例。该作用域被称为 singleton,它是所有 Bean 的默认作用域。

Spring 容器中的 bean 能够分为 5 个范畴。所有范畴的名称都是自阐明的,然而为了防止混同,还是让咱们来解释一下:

  1. singleton:这种bean范畴是默认的,这种范畴确保不论承受到多少个申请,每个容器中只有一个bean的实例,单例的模式由bean factory本身来保护。
  2. prototype:原型范畴与单例范畴相同,为每一个bean申请提供一个实例。
  3. request:每次HTTP申请都会创立一个新的bean,该作用于仅实用于WebApplicationContext环境,在申请实现当前,bean会生效并被垃圾回收器回收。
  4. Session:同一个HTTP Session 共享一个bean,不同的 HTTP Session应用不同的bean。该作用于仅实用于WebApplicationContext环境,在session过期后,bean会随之生效。
  5. global-session:全局session作用域,仅仅在基于portlet的web利用中才有意义,Spring5曾经没有了。Portlet是可能生成语义代码(例如:HTML)片段的小型Java Web插件。它们基于portlet容器,能够像servlet一样解决HTTP申请。然而,与 servlet 不同,每个 portlet 都有不同的会话

全局作用域与Servlet中的session作用域成果雷同。

Spring bean 容器的生命周期是什么样的?

Spring IOC 容器能够治理 Bean 的生命周期, Spring 容许在 Bean 生命周期的特定点执行定制的工作。

Spring bean 容器的生命周期流程如下:

  1. Spring 容器依据配置中的 bean 定义实例化 bean;
  2. Spring 应用依赖注入填充所有属性,如 bean 中所定义的配置;
  3. 如果 bean 实现 BeanNameAware 接口,则工厂通过传递 bean 的 ID 来调用 setBeanName();
  4. 如果 bean 实现 BeanFactoryAware 接口,工厂通过传递本身的实例来调用 setBeanFactory();
  5. 与下面的相似,如果实现了其余 *.Aware接口,就调用相应的办法;
  6. 如果存在与 bean 关联的任何 BeanPostProcessors,则调用 preProcessBeforeInitialization() 办法;
  7. 如果为 bean 指定了 init 办法(<bean> 的 init-method 属性),那么将调用它;
  8. 最初,如果存在与 bean 关联的任何 BeanPostProcessors,则将调用 postProcessAfterInitialization() 办法;
  9. 如果 bean 实现 DisposableBean 接口,当 spring 容器敞开时,会调用 destory();
  10. 如果为 bean 指定了 destroy 办法(<bean> 的 destroy-method 属性),那么将调用它

在 bean 初始化时会经验几个阶段,要与容器对 bean 生命周期的治理交互,能够实现 InitializingBeanDisposableBean 接口。容器对前者调用 afterPropertiesSet(),对后者调用 destroy(),以容许 bean 在初始化和销毁 bean 时执行某些操作。

官网不倡议应用这两个接口,而是倡议应用 @PostConstruct@PreDestroy,或者 XML 配置中应用 init-methoddestroy-method 属性

<bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>
public class ExampleBean {    public void init() {        // do some initialization work    }}

等价于

public class AnotherExampleBean implements InitializingBean {    public void afterPropertiesSet() {        // do some initialization work    }}
Spring Bean生命周期回调——初始化回调和销毁回调办法

实现 Bean 初始化回调和销毁回调各有三种办法,一是实现接口办法,二是在XML配置,三是应用注解

  • 应用注解 @PostConstruct@PreDestroy
  • 实现 InitializingBeanDisposableBean 接口
  • XML 中配置 init-methoddestroy-method

在一个 bean 中,如果配置了多种生命周期回调机制,会依照上边从上到下的秩序调用

在 Spring 中如何配置 Bean?

Bean 的配置形式: 通过全类名 (反射)、 通过工厂办法 (动态工厂办法 & 实例工厂办法)、FactoryBean

什么是 Spring 拆卸

当 bean 在 Spring 容器中组合在一起时,它被称为拆卸或 bean 拆卸,拆卸是创立利用对象之间协作关系的行为。 Spring 容器须要晓得须要什么 bean 以及容器应该如何应用依赖注入来将 bean 绑定在一起,同时拆卸 bean。

依赖注入的实质就是拆卸,拆卸是依赖注入的具体行为。

注入是实例化的过程,将创立的bean放在Spring容器中,分为属性注入(setter形式)、结构器注入

什么是bean主动拆卸?

Spring 容器能够主动配置相互协作 beans 之间的关联关系。这意味着 Spring 能够主动配置一个 bean 和其余合作bean 之间的关系,通过查看 BeanFactory 的内容里有没有应用< property>元素。

在Spring框架中共有5种主动拆卸,让咱们逐个剖析

  1. no:这是Spring框架的默认设置,在该设置下主动拆卸是敞开的,开发者须要自行在beanautowire属性里指定主动拆卸的模式
  2. byName:该选项能够依据bean名称设置依赖关系。当向一个bean中主动拆卸一个属性时,容器将依据bean的名称主动在在配置文件中查问一个匹配的bean。如果找到的话,就拆卸这个属性,如果没找到的话就报错。
  3. byType:该选项能够依据bean类型设置依赖关系。当向一个bean中主动拆卸一个属性时,容器将依据bean的类型主动在在配置文件中查问一个匹配的bean。如果找到的话,就拆卸这个属性,如果没找到的话就报错。
  4. constructor:结构器的主动拆卸和byType模式相似,然而仅仅实用于与有结构器雷同参数的bean,如果在容器中没有找到与结构器参数类型统一的bean,那么将会抛出异样。
  5. autodetect:Spring首先尝试通过 constructor 应用主动拆卸来连贯,如果它不执行,Spring 尝试通过 byType 来主动拆卸

主动拆卸有什么局限?

  • 根本数据类型的值、字符串字面量、类字面量无奈应用主动拆卸来注入。
  • 拆卸依赖中若是呈现匹配到多个bean(呈现歧义性),拆卸将会失败

通过注解的形式配置bean | 什么是基于注解的容器配置

组件扫描(component scanning): Spring 可能从 classpath下主动扫描, 侦测和实例化具备特定注解的组件。

特定组件包含:

  • @Component:根本注解, 标识了一个受 Spring 治理的组件
  • @Respository:标识长久层组件
  • @Service:标识服务层(业务层)组件
  • @Controller: 标识体现层组件

对于扫描到的组件,,Spring 有默认的命名策略:应用非限定类名,,第一个字母小写。也能够在注解中通过 value 属性值标识组件的名称。

当在组件类上应用了特定的注解之后,,还须要在 Spring 的配置文件中申明 <context:component-scan>

  • base-package 属性指定一个须要扫描的基类包,Spring 容器将会扫描这个基类包里及其子包中的所有类
  • 当须要扫描多个包时, 能够应用逗号分隔
  • 如果仅心愿扫描特定的类而非基包下的所有类,可应用 resource-pattern 属性过滤特定的类,示例:

    <context:component-scan base-package="priv.starfish.front.web.controller"    annotation-config="true" resource-pattern="autowire/*.class"/>

如何在 spring 中启动注解拆卸?

默认状况下,Spring 容器中未关上注解拆卸。因而,要应用基于注解拆卸,咱们必须通过配置<context:annotation-config /> 元素在 Spring 配置文件中启用它。

四、AOP

:形容一下Spring AOP 呗?

你有没有⽤过Spring的AOP? 是⽤来⼲嘛的? ⼤概会怎么使⽤?

什么是 AOP?

AOP(Aspect-Oriented Programming,面向切面编程):是一种新的方法论,是对传统 OOP(Object-Oriented Programming,面向对象编程) 的补充。在 OOP 中, 咱们以类(class)作为咱们的根本单元,而 AOP 中的根本单元是 Aspect(切面)

AOP 的次要编程对象是切面(aspect)

在利用 AOP 编程时, 依然须要定义公共性能,但能够明确的定义这个性能在哪里,,以什么形式利用,,并且不用批改受影响的类。这样一来横切关注点就被模块化到非凡的对象(切面)里。

AOP 的益处:

  • 每个事物逻辑位于一个地位,代码不扩散,便于保护和降级
  • 业务模块更简洁, 只蕴含外围业务代码

AOP 术语

  • 切面(Aspect):横切关注点(逾越应用程序多个模块的性能),被模块化的非凡对象
  • 连接点(Joinpoint):程序执行的某个特定地位,如类某个办法调用前、调用后、办法抛出异样后等。在这个地位咱们能够插入一个 AOP 切面,它实际上是应用程序执行 Spring AOP 的地位

  • 告诉(Advice): 告诉是个在办法执行前或执行后要做的动作,实际上是程序执行时要通过 SpringAOP 框架触发的代码段。Spring 切面能够利用五种类型的告诉:

    • before: 前置告诉 , 在一个办法执行前被调用
    • after:在办法执行之后调用的告诉,无论形式执行是否胜利
    • after-returning:仅当办法胜利实现后执行的告诉
    • after-throwing:在办法抛出异样退出时执行的告诉
    • around:在办法执行之前和之后调用的告诉

  • 指标(Target):被告诉的对象,通常是一个代理对象,也指被告诉(advice)对象
  • 代理(Proxy):向指标对象利用告诉之后创立的对象
  • 切点(pointcut):每个类都领有多个连接点,程序运行中的一些工夫点,例如一个办法的执行,或者是一个异样的解决。AOP 通过切点定位到特定的连接点。类比:连接点相当于数据库中的记录,切点相当于查问条件。切点和连接点不是一对一的关系,一个切点匹配多个连接点,切点通过 org.springframework.aop.Pointcut 接口进行形容,它应用类和办法作为连接点的查问条件
  • 引入(Introduction):引入容许咱们向现有的类增加新办法或属性
  • 织入(Weaving):织入是把切面利用到指标对象并创立新的代理对象的过程

Spring AOP

  • AspectJ:Java 社区里最残缺最风行的 AOP 框架
  • 在 Spring2.0 以上版本中, 能够应用基于 AspectJ 注解或基于 XML 配置的 AOP

在 Spring 中启用 AspectJ 注解反对

  • 要在 Spring 利用中应用 AspectJ 注解, 必须在 classpath 下蕴含 AspectJ 类库:aopalliance.jaraspectj.weaver.jarspring-aspects.jar
  • 将 aop Schema 增加到 <beans> 根元素中.
  • 要在 Spring IOC 容器中启用 AspectJ 注解反对, 只有在 Bean 配置文件中定义一个空的 XML 元素 <aop:aspectj-autoproxy>
  • 当 Spring IOC 容器侦测到 Bean 配置文件中的 <aop:aspectj-autoproxy> 元素时, 会主动为与 AspectJ切面匹配的 Bean 创立代理.

有哪写类型的告诉(Advice) | 用 AspectJ 注解申明切面

  • 要在 Spring 中申明 AspectJ切面, 只须要在 IOC 容器中将切面申明为 Bean 实例. 当在 Spring IOC 容器中初始化 AspectJ切面之后, Spring IOC 容器就会为那些与 AspectJ切面相匹配的 Bean 创立代理.
  • 在 AspectJ注解中, 切面只是一个带有 @Aspect 注解的 Java 类.
  • 告诉是标注有某种注解的简略的 Java 办法.
  • AspectJ反对 5 种类型的告诉注解:

    • @Before: 前置告诉, 在办法执行之前执行
    • @After: 后置告诉, 在办法执行之后执行
    • @AfterRunning: 返回告诉, 在办法返回后果之后执行
    • @AfterThrowing: 异样告诉, 在办法抛出异样之后
    • @Around: 盘绕告诉, 围绕着办法执行

AOP 有哪些实现形式?

实现 AOP 的技术,次要分为两大类:

  • 动态代理 - 指应用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代理类,因而也称为编译时加强;

    • 编译时编织(非凡编译器实现)
    • 类加载时编织(非凡的类加载器实现)。
  • 动静代理 - 在运行时在内存中“长期”生成 AOP 动静代理类,因而也被称为运行时加强。

    • JDK 动静代理
    • CGLIB

有哪些不同的AOP实现

Spring AOP and AspectJ AOP 有什么区别?

  • Spring AOP 基于动静代理形式实现,AspectJ 基于动态代理形式实现。
  • Spring AOP 仅反对办法级别的 PointCut;提供了齐全的 AOP 反对,它还反对属性级别的 PointCut。

五、数据拜访

Spring对JDBC的反对

JdbcTemplate简介

  • 为了使 JDBC 更加易于应用, Spring 在 JDBC API 上定义了一个形象层, 以此建设一个 JDBC 存取框架
  • 作为 Spring JDBC 框架的外围, JDBCTemplate 的设计目标是为不同类型的 JDBC 操作提供模板办法。每个模板办法都能管制整个过程,并容许笼罩过程中的特定工作。通过这种形式,能够在尽可能保留灵活性的状况下,将数据库存取的工作量降到最低。

Spring 反对哪些 ORM 框架

Hibernate、iBatis、JPA、JDO、OJB

六、事务

Spring 中的事务管理

作为企业级应用程序框架,,Spring 在不同的事务管理 API 之上定义了一个形象层,而应用程序开发人员不用理解底层的事务管理 API,就能够应用 Spring 的事务管理机制

Spring 既反对编程式事务管理,也反对申明式的事务管理

  • 编程式事务管理:将事务管理代码嵌入到业务办法中来管制事务的提交和回滚,在编程式治理事务时,必须在每个事务操作中蕴含额定的事务管理代码,属于硬编码
  • 申明式事务管理:大多数状况下比编程式事务管理更好用。它将事务管理代码从业务办法中分离出来,以申明的形式来实现事务管理。事务管理作为一种横切关注点,能够通过 AOP 办法模块化。Spring 通过 Spring AOP 框架反对申明式事务管理,申明式事务又分为两种:

    • 基于XML的申明式事务
    • 基于注解的申明式事务

事务管理器

Spring 并不间接治理事务,而是提供了多种事务管理器,他们将事务管理的职责委托给 Hibernate 或者 JTA 等长久化机制所提供的相干平台框架的事务来实现。

Spring 事务管理器的接口是 org.springframework.transaction.PlatformTransactionManager,通过这个接口,Spring为各个平台如 JDBC、Hibernate 等都提供了对应的事务管理器,然而具体的实现就是各个平台本人的事件了。

Spring 中的事务管理器的不同实现

事务管理器以一般的 Bean 模式申明在 Spring IOC 容器中

  • 在应用程序中只须要解决一个数据源, 而且通过 JDBC 存取

    org.springframework.jdbc.datasource.DataSourceTransactionManager
  • 在 JavaEE 应用服务器上用 JTA(Java Transaction API) 进行事务管理

    org.springframework.transaction.jta.JtaTransactionManager
  • 用 Hibernate 框架存取数据库

    org.springframework.orm.hibernate3.HibernateTransactionManager

事务管理器以一般的 Bean 模式申明在 Spring IOC 容器中

用事务告诉申明式地治理事务

  • 事务管理是一种横切关注点
  • 为了在 Spring 2.x 中启用申明式事务管理,能够通过 tx Schema 中定义的 \<tx:advice> 元素申明事务告诉,为此必须当时将这个 Schema 定义增加到 \<beans> 根元素中去
  • 申明了事务告诉后,就须要将它与切入点关联起来。因为事务告诉是在 \<aop:config> 元素内部申明的, 所以它无奈间接与切入点产生关联,所以必须在 \<aop:config> 元素中申明一个增强器告诉与切入点关联起来.
  • 因为 Spring AOP 是基于代理的办法,所以只能加强公共办法。因而, 只有私有办法能力通过 Spring AOP 进行事务管理。

用 @Transactional 注解申明式地治理事务

  • 除了在带有切入点,告诉和增强器的 Bean 配置文件中申明事务外,Spring 还容许简略地用 @Transactional 注解来标注事务办法
  • 为了将办法定义为反对事务处理的,能够为办法增加 @Transactional 注解,依据 Spring AOP 基于代理机制,只能标注私有办法.
  • 能够在办法或者类级别上增加 @Transactional 注解。当把这个注解利用到类上时, 这个类中的所有公共办法都会被定义成反对事务处理的
  • 在 Bean 配置文件中只须要启用 <tx:annotation-driven>元素, 并为之指定事务管理器就能够了
  • 如果事务处理器的名称是 transactionManager, 就能够在 <tx:annotation-driven> 元素中省略 transaction-manager 属性,这个元素会自动检测该名称的事务处理器

事务流传属性

  • 当事务办法被另一个事务办法调用时, 必须指定事务应该如何流传。例如:办法可能持续在现有事务中运行,也可能开启一个新事务,并在本人的事务中运行
  • 事务的流传行为能够由流传属性指定,Spring 定义了 7 品种流传行为:
流传行为意义
PROPAGATION_MANDATORY示意该办法必须运行在一个事务中。如果以后没有事务正在产生,将抛出一个异样
PROPAGATION_NESTED示意如果以后正有一个事务在进行中,则该办法该当运行在一个嵌套式事务中。被嵌套的事务能够独立于封装事务进行提交或回滚。如果封装事务不存在,行为就像PROPAGATION_REQUIRES一样。
PROPAGATION_NEVER示意以后的办法不应该在一个事务中运行。如果一个事务正在进行,则会抛出一个异样。
PROPAGATION_NOT_SUPPORTED示意该办法不应该在一个事务中运行。如果一个现有事务正在进行中,它将在该办法的运行期间被挂起。
PROPAGATION_SUPPORTS示意以后办法不须要事务性上下文,然而如果有一个事务曾经在运行的话,它也能够在这个事务里运行。
PROPAGATION_REQUIRES_NEW示意以后办法必须在它本人的事务里运行。一个新的事务将被启动,而且如果有一个现有事务在运行的话,则将在这个办法运行期间被挂起。
PROPAGATION_REQUIRES示意以后办法必须在一个事务中运行。如果一个现有事务正在进行中,该办法将在那个事务中运行,否则就要开始一个新事务。

Spring 反对的事务隔离级别

隔离级别含意
ISOLATION_DEFAULT应用后端数据库默认的隔离级别。
ISOLATION_READ_UNCOMMITTED容许读取尚未提交的更改。可能导致脏读、幻影读或不可反复读。
ISOLATION_READ_COMMITTED容许从曾经提交的并发事务读取。可避免脏读,但幻影读和不可反复读仍可能会产生。
ISOLATION_REPEATABLE_READ对雷同字段的屡次读取的后果是统一的,除非数据被以后事务自身扭转。可避免脏读和不可反复读,但幻影读仍可能产生。
ISOLATION_SERIALIZABLE齐全遵从ACID的隔离级别,确保不产生脏读、不可反复读和幻影读。这在所有隔离级别中也是最慢的,因为它通常是通过齐全锁定以后事务所波及的数据表来实现的。

事务的隔离级别要失去底层数据库引擎的反对,而不是应用程序或者框架的反对;

Oracle 反对的 2 种事务隔离级别,Mysql反对 4 种事务隔离级别。

设置隔离事务属性

用 @Transactional 注解申明式地治理事务时能够在 @Transactional 的 isolation 属性中设置隔离级别

在 Spring 事务告诉中, 能够在 <tx:method> 元素中指定隔离级别

设置回滚事务属性

  • 默认状况下只有未查看异样(RuntimeException和Error类型的异样)会导致事务回滚,而受查看异样不会。
  • 事务的回滚规定能够通过 @Transactional 注解的 rollbackFor和 noRollbackFor属性来定义,这两个属性被申明为 Class[] 类型的,因而能够为这两个属性指定多个异样类。

    • rollbackFor:遇到时必须进行回滚
    • noRollbackFor: 一组异样类,遇到时必须不回滚

超时和只读属性

  • 因为事务能够在行和表上取得锁, 因而长事务会占用资源, 并对整体性能产生影响
  • 如果一个事物只读取数据但不做批改,数据库引擎能够对这个事务进行优化
  • 超时事务属性:事务在强制回滚之前能够放弃多久,这样能够避免长期运行的事务占用资源
  • 只读事务属性:示意这个事务只读取数据但不更新数据,这样能够帮忙数据库引擎优化事务

设置超时和只读事务属性

  • 超时和只读属性能够在 @Transactional 注解中定义,超时属性以秒为单位来计算

列出两种形式的示例:

@Transactional(propagation = Propagation.NESTED, timeout = 1000, isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
    <tx:advice id="txAdvice" transaction-manager="txManager">        <!-- the transactional semantics... -->        <tx:attributes>            <!-- all methods starting with 'get' are read-only -->            <tx:method name="get*" read-only="true" propagation="REQUIRES_NEW" isolation="READ_COMMITTED" timeout="30" no-rollback-for="java.lang.ArithmeticException"/>            <!-- other methods use the default transaction settings (see below) -->            <tx:method name="*"/>        </tx:attributes>    </tx:advice>    <!-- ensure that the above transactional advice runs for any execution        of an operation defined by the FooService interface -->    <aop:config>        <aop:pointcut id="fooServiceOperation" expression="execution(* x.y.service.FooService.*(..))"/>        <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/>    </aop:config>

七、MVC

Spring MVC 框架有什么用?

Spring Web MVC 框架提供 模型-视图-控制器 架构和随时可用的组件,用于开发灵便且涣散耦合的 Web 应用程序。 MVC 模式有助于拆散应用程序的不同方面,如输出逻辑,业务逻辑和 UI 逻辑,同时在所有这些元素之间提供涣散耦合。

Spring MVC的长处

  • 能够反对各种视图技术,而不仅仅局限于JSP
  • 与Spring框架集成(如IoC容器、AOP等)
  • 清晰的角色调配:前端控制器(dispatcherServlet) ,申请到处理器映射(handlerMapping),处理器适配器(HandlerAdapter), 视图解析器(ViewResolver)
  • 反对各种申请资源的映射策略

Spring MVC 的运行流程 | DispatcherServlet形容

在整个 Spring MVC 框架中, DispatcherServlet 处于外围地位,负责协调和组织不同组件以实现申请解决并返回响应的工作

SpringMVC 解决申请过程:

  1. 若一个申请匹配 DispatcherServlet 的申请映射门路(在 web.xml中指定),WEB 容器将该申请转交给 DispatcherServlet 解决
  2. DispatcherServlet 接管到申请后, 将依据申请信息(包含 URL、HTTP办法、申请头、申请参数、Cookie 等)及 HandlerMapping 的配置找到解决申请的处理器(Handler)。可将 HandlerMapping 看成路由控制器, 将 Handler 看成指标主机
  3. 当 DispatcherServlet 依据 HandlerMapping 失去对应以后申请的 Handler 后,通过 HandlerAdapter 对 Handler 进行封装,再以对立的适配器接口调用 Handler
  4. 处理器实现业务逻辑的解决后将返回一个 ModelAndView 给 DispatcherServlet,ModelAndView 蕴含了视图逻辑名和模型数据信息
  5. DispatcherServlet 借助 ViewResoler 实现逻辑视图名到实在视图对象的解析
  6. 失去实在视图对象 View 后, DispatcherServlet 应用这个 View 对ModelAndView 中的模型数据进行视图渲染

Spring的Controller是单例的吗?多线程状况下Controller是线程平安吗?

controller默认是单例的,不要应用非动态的成员变量,否则会产生数据逻辑凌乱。正因为单例所以不是线程平安的

@Controller//@Scope("prototype")public class ScopeTestController {    private int num = 0;    @RequestMapping("/testScope")    public void testScope() {        System.out.println(++num);    }    @RequestMapping("/testScope2")    public void testScope2() {        System.out.println(++num);    }}

咱们首先拜访 http://localhost:8080/testScope,失去的答案是1
而后咱们再拜访 http://localhost:8080/testScope2,失去的答案是 2

接下来咱们再来给controller减少作用多例 @Scope("prototype")

咱们仍旧首先拜访 http://localhost:8080/testScope,失去的答案是1
而后咱们再拜访 http://localhost:8080/testScope2,失去的答案还是 1

单例是不平安的,会导致属性重复使用

解决方案
  1. 不要在controller中定义成员变量
  2. 万一必须要定义一个非动态成员变量时候,则通过注解@Scope(“prototype”),将其设置为多例模式。
  3. 在Controller中应用ThreadLocal变量

八、注解

什么是基于Java的Spring注解配置? 给一些注解的例子

基于Java的配置,容许你在大量的Java注解的帮忙下,进行你的大部分Spring配置而非通过XML文件。

以@Configuration 注解为例,它用来标记类能够当做一个bean的定义,被Spring IOC容器应用。

另一个例子是@Bean注解,它示意此办法将要返回一个对象,作为一个bean注册进Spring利用上下文。

@Configurationpublic class StudentConfig {    @Bean    public StudentBean myStudent() {        return new StudentBean();    }}

怎么开启注解拆卸?

注解拆卸在默认状况下是不开启的,为了应用注解拆卸,咱们必须在Spring配置文件中配置 <context:annotation-config/> 元素。

Spring MVC 罕用注解:

@Controller

在SpringMVC 中,控制器Controller 负责解决由DispatcherServlet 散发的申请,它把用户申请的数据通过业务解决层解决之后封装成一个Model ,而后再把该Model 返回给对应的View 进行展现。在SpringMVC 中只需应用@Controller 标记一个类是Controller ,而后应用@RequestMapping 和@RequestParam 等一些注解用以定义URL 申请和Controller 办法之间的映射,这样的Controller 就能被外界拜访到。

@RequestMapping

RequestMapping是一个用来解决申请地址映射的注解,可用于类或办法上

@RequestMapping

Spring Framework 4.3 之后引入的基于HTTP办法的变体

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping
  • @PatchMapping
@PathVariable

用于将申请URL中的模板变量映射到性能解决办法的参数上,即取出uri模板中的变量作为参数

@RequestParam

应用@RequestParam绑定申请参数值,在解决办法入参处应用@RequestParam能够把申请参数传递给申请办法

  • value:参数名
  • required:是否必须。默认为true, 示意申请参数中必须蕴含对应的参数,若不存在,将抛出异样
@RequestBody

@RequestBody 表明办法参数应该绑定到HTTP申请体的值

@ResponseBody

@Responsebody 示意该办法的返回后果间接写入HTTP response body中

个别在异步获取数据时应用,在应用@RequestMapping后,返回值通常解析为跳转门路,加上@Responsebody后返回后果不会被解析为跳转门路,而是间接写入HTTP response body中。比方异步获取 json 数据,加上@Responsebody后,会间接返回 json 数据。

@Resource和@Autowired

@Resource和@Autowired都是做bean的注入时应用,其实@Resource并不是Spring的注解,它的包是javax.annotation.Resource,须要导入,然而Spring反对该注解的注入。

  • 共同点:两者都能够写在字段和 setter 办法上。两者如果都写在字段上,那么就不须要再写 setter 办法。
  • 不同点

    • @Autowired 为 Spring 提供的注解,@Autowired 注解是依照类型(byType)拆卸依赖对象,默认状况下它要求依赖对象必须存在,如果容许 null 值,能够设置它的 required 属性为 false。如果咱们想应用依照名称(byName)来拆卸,能够联合 @Qualifier 注解一起应用
    • @Resource 默认依照 ByName 主动注入,由 J2EE 提供,须要导入包 javax.annotation.Resource。@Resource 有两个重要的属性:name 和 type,而 Spring 将@ Resource 注解的 name 属性解析为bean 的名字,而 type 属性则解析为 bean 的类型。所以,如果应用 name 属性,则应用 byName 的主动注入策略,而应用 type 属性时则应用 byType 主动注入策略。如果既不制订 name 也不制订 type 属性,这时将通过反射机制应用 byName 主动注入策略。
@ModelAttribute

办法入参标注该注解后, 入参的对象就会放到数据模型中

@SessionAttribute

将模型中的某个属性暂存到HttpSession中,以便多个申请之间能够共享这个属性

@CookieValue

@CookieValue可让解决办法入参绑定某个Cookie 值

@RequestHeader

申请头蕴含了若干个属性,服务器可据此获知客户端的信息,通过@RequestHeader即可将申请头中的属性值绑定到解决办法的入参中

@Component, @Controller, @Repository, @Service 有何区别?

  • @Component:将 java 类标记为 bean。它是任何 Spring 治理组件的通用构造型。Spring 的组件扫描机制能够将其拾取并将其拉入应用程序环境中
  • @Controller:将一个类标记为 Spring Web MVC 控制器。标有它的 Bean 会主动导入到 IoC 容器中
  • @Service:此注解是组件注解的特化。它不会对 @Component 注解提供任何其余行为。你能够在服务层类中应用 @Service 而不是 @Component,因为它以更好的形式指定了用意
  • @Repository:这个注解是具备相似用处和性能的 @Component 注解的特化。它为 DAO 提供了额定的益处。它将 DAO 导入 IoC 容器,并使未经查看的异样有资格转换为 Spring DataAccessException。

@Required 注解有什么作用

这个注解表明bean的属性必须在配置的时候设置,通过一个bean定义的显式的属性值或通过主动拆卸,若@Required注解的bean属性未被设置,容器将抛出 BeanInitializationException。示例:

public class Employee {    private String name;    @Required    public void setName(String name){        this.name=name;    }    public string getName(){        return name;    }}

@Autowired 注解有什么作用

@Autowired默认是依照类型拆卸注入的,默认状况下它要求依赖对象必须存在(能够设置它required属性为false)。@Autowired 注解提供了更细粒度的管制,包含在何处以及如何实现主动拆卸。它的用法和@Required一样,润饰setter办法、结构器、属性或者具备任意名称和/或多个参数的PN办法。

public class Employee {    private String name;    @Autowired    public void setName(String name) {        this.name=name;    }    public string getName(){        return name;    }}

@Autowired和@Resource之间的区别

用处:做bean的注入时应用

  • @Autowired,属于Spring的注解,org.springframework.beans.factory.annotation.Autowired    
  • @Resource,不属于Spring的注解,JDK1.6反对的注解,javax.annotation.Resource

共同点:都用来拆卸bean。写在字段上,或写在setter办法

不同点:@Autowired 默认按类型拆卸。依赖对象必须存在,如果要容许null值,能够设置它的required属性为false @Autowired(required=false),也能够应用名称拆卸,配合@Qualifier注解

@Resource默认是依照名称来拆卸注入的,只有当找不到与名称匹配的bean才会依照类型来拆卸注入

@Qualifier 注解有什么作用

当创立多个雷同类型的 bean 并心愿仅应用属性拆卸其中一个 bean 时,能够应用 @Qualifier 注解和 @Autowired 通过指定应该拆卸哪个确切的 bean 来打消歧义。

@RequestMapping 注解有什么用?

@RequestMapping 注解用于将特定 HTTP 申请办法映射到将解决相应申请的控制器中的特定类/办法。此正文可利用于两个级别:

  • 类级别:映射申请的 URL
  • 办法级别:映射 URL 以及 HTTP 申请办法

九、其余问题

Spring 框架中用到了哪些设计模式?

  • 工厂设计模式 : Spring应用工厂模式通过 BeanFactoryApplicationContext 创立 bean 对象。
  • 代理设计模式 : Spring AOP 性能的实现。
  • 单例设计模式 : Spring 中的 Bean 默认都是单例的。
  • 模板办法模式 : Spring 中 jdbcTemplatehibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就应用到了模板模式。
  • 包装器设计模式 : 咱们的我的项目须要连贯多个数据库,而且不同的客户在每次拜访中依据须要会去拜访不同的数据库。这种模式让咱们能够依据客户的需要可能动静切换不同的数据源。
  • 观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个利用。
  • 适配器模式 :Spring AOP 的加强或告诉(Advice)应用到了适配器模式、spring MVC 中也是用到了适配器模式适配Controller

参考与起源

https://www.edureka.co/blog/interview-questions/spring-interv...

https://crossoverjie.top/2018/07/29/java-senior/ThreadPool/

本文由mdnice多平台公布