spring面试题(二)

目录

硅谷

一 .请写出 spring 中常用的依赖注入方式。

二  .简述Spring中IOC容器常用的接口和具体的实现类

三 .简述Spring中如何基于注解配置Bean和装配Bean 

四.  说出Spring 或者 Springmvc中常用的5个注解,并解释含义

五.请解释Spring Bean的生命周期?

六.简述Spring 中bean的作用域

七. 简述Spring中自动装配常用的两种装配模式

八. 请解释@Autowired注解的工作机制及required属性的作用

九.  简述Spring声明式事务中@Transaction中常用的两种事务传播行为

十. 简述Spring中切面中常用的几种通知,并简单解释

十一 .谈谈你对Spring 的理解

十二   Spring中常用的设计模式 

十三  请描述一下Spring的事务管理

十四 .Spring 支持的事务管理类型有哪些?你在项目中使用哪种方式?怎么理解全局事务和局部事务?

十五 .Spring循环依赖问题

常见问法

什么是循环依赖?

两种注入方式对循环依赖的影响?

相关概念

三级缓存

四个关键方法

debug源代码过程

总结

其他衍生问题

黑马  

一 .谈谈你对 Spring 的理解?

二  . IOC 是什么?

三  IOC 原理

四   IOC 的使用场景?

五  IOC 中 Bean 有几种注入方式?

六   SpringBean 自动装配的几种方式?

七  AOP 是什么?

八    AOP 主要用在哪些场景中?

九   SpringBean 的作用域有几种

十  Spring 事务管理方式?

十一   Spring 事务传播行为有几种?

十二   Spring 中的事务隔离级别?

十三   Spring 中的设计模式有哪些?

十四     Spring 的常用注解有哪些?(重要)

十五   @Resources 和@Autowired 的区别?

以下为重点记忆

黑马

一  .Spring的两大核心是什么?谈一谈你对IOC的理解? 谈一谈你对DI的理解?  谈一谈你对 AOP 的理解?(必会)

二 .Spring 的生命周期?(高薪常问)

三    Spring 支持 bean 的作用域有几种吗? 每种作用域是什么样的?(必会)

四  BeanFactory 和 ApplicationContext 有什么区别(了解)

五    Spring 框架中都用到了哪些设计模式?(必会)

六    Spring 事务的实现方式和实现原理(必会)

七   你知道的 Spring 的通知类型有哪些,分别在什么时候执行?(了解)

八    Spring 的对象默认是单例的还是多例的? 单例 bean 存不存在线程安全问

题呢?(必会)

九  @Resource 和@Autowired 依赖注入的区别是什么? @Qualifier 使用场

景是什么?(了解)

十   Spring 的常用注解(必会)  非常重要

十一    Spring 的事务传播行为(高薪常问)

十二    Spring 中的隔离级别 (高薪常问)

动力节点2021

一  . 什么是 Spring 框架?

二  列举一些重要的Spring模块?

三  Spring 中的设计模式

四    什么是Ioc及其优点

五  IOC容器的初始化过程

六      Spring 提供了多种依赖注入的方式

七   Spring中,如何给对象的属性赋值?

 八  bean对象创建的细节

九   Bean的作用域?

十  Bean的生命周期

十 一  BeanFactory和ApplicationContext的区别?

十二    AOP

十三    事务


硅谷

一 .请写出 spring 中常用的依赖注入方式。

通过 setter 方法注入

通过构造方法注入

二  .简述Spring中IOC容器常用的接口和具体的实现类

  1. BeanFactory  SpringIOC容器的基本设置,是最底层的实现, 面向框架本身的.  
  2. ApplicationContext  BeanFactory的子接口, 提供了更多高级的特定. 面向开发者的.
  3. ConfigurableApplicationContext, ApplicationContext的子接口,扩展出了 close 和 refresh等 关闭 刷新容器的方法
  4. ClassPathXmlApplicationContext:从classpath的XML配置文件中读取上下文,并生成上下文定义。应用程序上下文从程序环境变量中取得。
  5. FileSystemXmlApplicationContext :由文件系统中的XML配置文件读取上下文。
  6. XmlWebApplicationContext:由Web应用的XML文件读取上下文。

三 .简述Spring中如何基于注解配置Bean和装配Bean 

(1)首先要在Spring中配置开启注解扫描

<context:component-scan base-package=” ”></ context:component-scan>

(2)在具体的类上加上具体的注解

(3)Spring 中通常使用@Autowired 或者是@Resource 等注解进行bean的装配

四.  说出Spring 或者 Springmvc中常用的5个注解,并解释含义

@Component  基本注解,标识一个受Spring管理的组件

@Controller    标识为一个表示层的组件

@Service       标识为一个业务层的组件

@Repository    标识为一个持久层的组件

@Autowired     自动装配

@Qualifier(“”)    具体指定要装配的组件的id值

@RequestMapping()  完成请求映射

@PathVariable    映射请求URL中占位符到请求处理方法的形参

五.请解释Spring Bean的生命周期?

(1)默认情况下,IOC容器中bean的生命周期分为五个阶段:

  1. 调用构造器 或者是通过工厂的方式创建Bean对象
  2. 给bean对象的属性注入值
  3. 调用初始化方法,进行初始化, 初始化方法是通过init-method来指定的.
  4. 使用
  5. IOC容器关闭时, 销毁Bean对象.

(2)当加入了Bean的后置处理器后,IOC容器中bean的生命周期分为七个阶段:

  1. 调用构造器 或者是通过工厂的方式创建Bean对象
  2. 给bean对象的属性注入值 
  3. 执行Bean后置处理器中的 postProcessBeforeInitialization
  4. 调用初始化方法,进行初始化, 初始化方法是通过init-method来指定的.
  5. 执行Bean的后置处理器中 postProcessAfterInitialization   
  6. 使用
  7. IOC容器关闭时, 销毁Bean对象

六.简述Spring 中bean的作用域

总共有四种作用域:

  1. Singleton  单例的
  2. Prototype  原型的
  3. Request
  4. Session

七. 简述Spring中自动装配常用的两种装配模式

byName:  根据bean对象的属性名进行装配

byType: 根据bean对象的属性的类型进行装配,需要注意匹配到多个兼容类型的bean对象时,会抛出异常。

八. 请解释@Autowired注解的工作机制及required属性的作用

(1)首先会使用byType的方式进行自动装配,如果能唯一匹配,则装配成功,

如果匹配到多个兼容类型的bean, 还会尝试使用byName的方式进行唯一确定.

如果能唯一确定,则装配成功,如果不能唯一确定,则装配失败,抛出异常.

(2)默认情况下, 使用@Autowired标注的属性必须被装配,如果装配不了,也会抛出异常.

可以使用required=false来设置不是必须要被装配.

九.  简述Spring声明式事务中@Transaction中常用的两种事务传播行为

通过propagation来执行事务的传播行为

REQUIRED:使用调用者的事务,如果调用者没有事务,则启动新的事务运行

REQUIRES_NEW:将调用者的事务挂起,开启新的事务运行。

十. 简述Spring中切面中常用的几种通知,并简单解释

前置通知  在目标方法执行之前执行

后置通知  在目标方法执行之后执行,不管目标方法有没有抛出异常

返回通知  在目标方法成功返回之后执行, 可以获取到目标方法的返回值

异常通知  在目标方法抛出异常后执行

环绕通知  环绕着目标方法执行

十一 .谈谈你对Spring 的理解

Spring 是一个开源框架,为简化企业级应用开发而生。Spring 可以是使简单的JavaBean 实现以前只有EJB 才能实现的功能。Spring 是一个 IOC 和 AOP 容器框架。

Spring 容器的主要核心是:

控制反转(IOC),传统的 java 开发模式中,当需要一个对象时,我们会自己使用 new 或者 getInstance 等直接或者间接调用构造方法创建一个对象。而在 spring 开发模式中,spring 容器使用了工厂模式为我们创建了所需要的对象,不需要我们自己创建了,直接调用spring 提供的对象就可以了,这是控制反转的思想。

依赖注入(DI),spring 使用 javaBean 对象的 set 方法或者带参数的构造方法为我们在创建所需对象时将其属性自动设置所需要的值的过程,就是依赖注入的思想。

面向切面编程(AOP),在面向对象编程(oop)思想中,我们将事物纵向抽成一个个的对象。而在面向切面编程中,我们将一个个的对象某些类似的方面横向抽成一个切面,对这个切面进行一些如权限控制、事物管理,记录日志等公用操作处理的过程就是面向切面编程的思想。AOP 底层是动态代理,如果是接口采用 JDK 动态代理,如果是类采用CGLIB 方式实现动态代理。

十二   Spring中常用的设计模式 

(1)代理模式——spring 中两种代理方式,若目标对象实现了若干接口,spring 使用jdk 的java.lang.reflect.Proxy类代理。若目标兑现没有实现任何接口,spring 使用 CGLIB 库生成目标类的子类。

(2)单例模式——在 spring 的配置文件中设置 bean 默认为单例模式。

(3)模板方式模式——用来解决代码重复的问题。

比如:RestTemplate、JmsTemplate、JpaTemplate

(4)工厂模式——在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用同一个接口来指向新创建的对象。Spring 中使用 beanFactory 来创建对象的实例。

十三  请描述一下Spring的事务管理

(1)声明式事务管理的定义:用在 Spring 配置文件中声明式的处理事务来代替代码式的处理事务。这样的好处是,事务管理不侵入开发的组件,具体来说,业务逻辑对象就不会意识到正在事务管理之中,事实上也应该如此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分,如果想要改变事务管理策划的话,也只需要在定义文件中重新配置即可,这样维护起来极其方便。

基于 TransactionInterceptor  的声明式事务管理:两个次要的属性: transactionManager,用来指定一个事务治理器, 并将具体事务相关的操作请托给它; 其他一个是 Properties 类型的transactionAttributes 属性,该属性的每一个键值对中,键指定的是方法名,方法名可以行使通配符, 而值就是表现呼应方法的所运用的事务属性。

(2)基于 @Transactional 的声明式事务管理:Spring 2.x 还引入了基于 Annotation 的体式格式,具体次要触及@Transactional 标注。@Transactional 可以浸染于接口、接口方法、类和类方法上。算作用于类上时,该类的一切public 方法将都具有该类型的事务属性。

(3)编程式事物管理的定义:在代码中显式挪用 beginTransaction()、commit()、rollback()等事务治理相关的方法, 这就是编程式事务管理。Spring 对事物的编程式管理有基于底层 API 的编程式管理和基于 TransactionTemplate 的编程式事务管理两种方式。

十四 .Spring 支持的事务管理类型有哪些?你在项目中使用哪种方式?怎么理解全局事务和局部事务?

Spring支持编程式事务管理和声明式事务管理。Spring框架的用户选择声明式事务管理,因为这种方式和应用程序的关联较少,因此更加符合轻量级容器的概念。声明式事务管理要优于编程式事务管理,尽管在灵活性方面它弱于编程式事务管理,因为编程式事务允许你通过代码控制业务。

事务分为全局事务和局部事务。全局事务由应用服务器管理,需要底层服务器JTA支持(如WebLogic、WildFly等)。局部事务和底层采用的持久化方案有关,例如使用JDBC进行持久化时,需要使用Connetion对象来操作事务;而采用Hibernate进行持久化时,需要使用Session对象来操作事务。

这些事务的父接口都是PlatformTransactionManager。Spring的事务管理机制是一种典型的策略模式,PlatformTransactionManager代表事务管理接口,该接口定义了三个方法,该接口并不知道底层如何管理事务,但是它的实现类必须提供getTransaction()方法(开启事务)、commit()方法(提交事务)、rollback()方法(回滚事务)的多态实现,这样就可以用不同的实现类代表不同的事务管理策略。使用JTA全局事务策略时,需要底层应用服务器支持,而不同的应用服务器所提供的JTA全局事务可能存在细节上的差异,因此实际配置全局事务管理器是可能需要使用JtaTransactionManager的子类,如:WebLogicJtaTransactionManager(Oracle的WebLogic服务器提供)、UowJtaTransactionManager(IBM的WebSphere服务器提供)等。

十五 .Spring循环依赖问题

常见问法

请解释一下spring中的三级缓存

三级缓存分别是什么?三个Map有什么异同?

什么是循环依赖?请你谈谈?看过spring源码吗?

如何检测是否存在循环依赖?实际开发中见过循环依赖的异常吗?

多例的情况下,循环依赖问题为什么无法解决?

什么是循环依赖?

两种注入方式对循环依赖的影响?

官方解释

https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-dependency-resolution

相关概念

实例化:堆内存中申请空间

初始化:对象属性赋值

 

三级缓存

四个关键方法

 

package org.springframework.beans.factory.support;

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

    /**

    单例对象的缓存:bean名称—bean实例,即:所谓的单例池。

    表示已经经历了完整生命周期的Bean对象

    第一级缓存

    */

    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

    /**

    早期的单例对象的高速缓存: bean名称—bean实例。

    表示 Bean的生命周期还没走完(Bean的属性还未填充)就把这个 Bean存入该缓存中也就是实例化但未初始化的 bean放入该缓存里

    第二级缓存

    */

    private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

    /**

    单例工厂的高速缓存:bean名称—ObjectFactory

    表示存放生成 bean的工厂

    第三级缓存

    */

    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

}

debug源代码过程

需要22个断点(可选)

1,A创建过程中需要B,于是A将自己放到三级缓里面,去实例化B

2,B实例化的时候发现需要A,于是B先查一级缓存,没有,再查二级缓存,还是没有,再查三级缓存,找到了A然后把三级缓存里面的这个A放到二级缓存里面,并删除三级缓存里面的A

3,B顺利初始化完毕,将自己放到一级缓存里面(此时B里面的A依然是创建中状态)

然后回来接着创建A,此时B已经创建结束,直接从一级缓存里面拿到B,然后完成创建,并将A自己放到一级缓存里面。

总结

1,Spring创建 bean主要分为两个步骤,创建原始bean对象,接着去填充对象属性和初始化。

2,每次创建 bean之前,我们都会从缓存中查下有没有该bean,因为是单例,只能有一个。

3,当创建 A的原始对象后,并把它放到三级缓存中,接下来就该填充对象属性了,这时候发现依赖了B,接着就又去创建B,同样的流程,创建完B填充属性时又发现它依赖了A又是同样的流程,不同的是:这时候可以在三级缓存中查到刚放进去的原始对象A。

所以不需要继续创建,用它注入 B,完成 B的创建既然 B创建好了,所以 A就可以完成填充属性的步骤了,接着执行剩下的逻辑,闭环完成

Spring解决循环依赖依靠的是Bean的"中间态"这个概念,而这个中间态指的是已经实例化但还没初始化的状态—>半成品。实例化的过程又是通过构造器创建的,如果A还没创建好出来怎么可能提前曝光,所以构造器的循环依赖无法解决

其他衍生问题

问题1:为什么构造器注入属性无法解决循环依赖问题?

       由于spring中的bean的创建过程为先实例化 再初始化(在进行对象实例化的过程中不必赋值)将实例化好的对象暴露出去,供其他对象调用,然而使用构造器注入,必须要使用构造器完成对象的初始化的操作,就会陷入死循环的状态

问题2:一级缓存能不能解决循环依赖问题? 不能

       在三个级别的缓存中存储的对象是有区别的 一级缓存为完全实例化且初始化的对象 二级缓存实例化但未初始化对象 如果只有一级缓存,如果是并发操作下,就有可能取到实例化但未初始化的对象,就会出现问题

问题3:二级缓存能不能解决循环依赖问题?

      理论上二级缓存可以解决循环依赖问题,但是需要注意,为什么需要在三级缓存中存储匿名内部类(ObjectFactory),原因在于 需要创建代理对象  eg:现有A类,需要生成代理对象 A是否需要进行实例化(需要) 在三级缓存中存放的是生成具体对象的一个匿名内部类,该类可能是代理类也可能是普通的对象,而使用三级缓存可以保证无论是否需要是代理对象,都可以保证使用的是同一个对象,而不会出现,一会儿使用普通bean 一会儿使用代理类

黑马  

一 .谈谈你对 Spring 的理解?

Spring 是一个 IOC AOP 容器框架。 Spring 容器的主要核心是:
控制反转( IOC ),传统的 java 开发模式中,当需要一个对象时,我们会自己
使用 new 或者 getInstance 等直接或者间接调用构造方法创建一个对象。而在
spring 开发模式中, spring 容器 使用了 工厂模式 为我们创建了所需要的对象,
不需要我们自己创建了,直接调用 spring 提供的对象就可以了,这是控制反
转的思想。
依赖注入( DI ), spring 使用 javaBean 对象的 set 方法或者带参数的构造方
为我们在创建所需对象时将其 属性自动设置所需要的值的过程 ,就是依赖注
入的思想。
面向切面编程( AOP ),在面向对象编程( oop )思想中,我们将事物纵向抽成
一个个的对象。而在面向切面编程中,我们将一个个的对象某些类似的方面横
向抽成一个切面,对这个切面进行一些如 权限控制、事物管理,记录日志 等。
公用操作处理的过程就是面向切面编程的思想。 AOP 底层是 动态代理 ,如果是
接口采用 JDK 动态代理 ,如果是类采用 CGLIB 方式 实现动态代理。

二  . IOC 是什么?

IOC Inversion Of Controll ,控制反转)是一种设计思想,就是将原本在程序中
手动创建对象的控制权,交由给 Spring 框架来管理。 IOC 在其他语言中也有应
用,并非 Spring 特有。 IOC 容器是 Spring 用来实现 IOC 的载体, IOC 容器实际
上就是一个 Map(key, value) Map 中存放 的是各种对象。
将对象之间的相互依赖关系交给 IOC 容器来管理,并由 IOC 容器完成对象的注入。
这样可以很 大程度上简化应用的开发,把应用从复杂的依赖关系中解放出来。 IOC
容器就像是一个工厂一 样,当我们需要创建一个对象的时候,只需要配置好配置文
/ 注解即可,完全不用考虑对象是 如何被创建出来的。在实际项目中一个 Service
类可能由几百甚至上千个类作为它的底层,假 如我们需要实例化这个 Service ,可
能要每次都搞清楚这个 Service 所有底层类的构造函数,这 可能会把人逼疯。如果
利用 IOC 的话,你只需要配置好,然后在需要的地方引用就行了,大大增加了项目
的可维护性且降低了开发难度

三  IOC 原理

解析流程: SpringBean new A()
根据路径、资源名称等方式,将 xml 文件、注解类加载到容器中
通过 BeanDefinitionReader 将对象解析成 BeanDefinition 实例
创建 BeanFactory 工厂 ( 注册前后需要添加 bean 前置、后置处理器 )
通过 BeanFactory 工厂将对象实例化、对象初始化 ( 初始化前后执行前置、后置处理
)
总结以上步骤,核心主干主要就是五部分构成:
1. 构造 Bean 对象
2. 设置 Bean 属性
3. 初始化回调
4. Bean 调用
5. 销毁 Bean

四   IOC 的使用场景?

正常情况下我们使用一个对象时都是需要 new Object() 的。而 ioc 是把需要使用的
对象提前创建好,放到 spring 的容器里面。需要使用的时候直接使用就行,而且可
以设置单例或多例,非常灵活。
我们在 service 层想调用另外一个 service 的方法,不需要去 new 了,直接把它交给
spring 管理,然后用注解的方式引入就能使用。
通过 XML 配置实例化 Bean ,将 bean 的信息配置 .xml 文件里,通过 Spring 加载
文件为我们创建 bean 和配置 bean 属性
通过注 解声明配置 通过在类上加注解的方式,来声明一个类交给 Spring 管理,
Spring 会自动扫描带有 @Component @Controller @Service @Repository
四个注解的类,然后帮我们创建并管理,前提是需要先配置 Spring 的注解扫描
器。
–@Component :可以用于注册所有 bean
–@Repository :主要用于注册 dao 层的 bean
–@Controller :主要用于注册控制层的 bean
–@Service :主要用于注册服务层的 bean
通过 配置类 将类的创建交给我们配置的 JavcConfig 类来完成, Spring 只负责维
护和管理创建一个配置类
添加 @Configuration 注解声明为配置类
方法上加上 @bean ,该方法用于创建实例并返回

五  IOC Bean 有几种注入方式?

构造器依赖注入 :构造器依赖注入通过容器触发一个类的构造器来实现的,该
类有一系列参数,每个参数代表一个对其他类的依赖。
Setter 方法注入 Setter 方法注入是容器通过调用无参构造器或无参 static
厂方法实例化 bean 之后,调用该 bean Setter 方法,即实现了基于
Setter 的依赖注入。
基于注解的注入 :最好的解决方案是用构造器参数实现强制依赖, Setter 方法
实现可选依赖

六   SpringBean 自动装配的几种方式?

自动装配提供五种不同的模式供 Spring 容器用来自动装配 beans 之间的依赖注入 :
• byName :通过 参数名自动装配 Spring 容器查找 beans 的属性,这些 beans
XML 配置文件 中被设置为 byName 。之后容器试图匹配、装配和该 bean 的属
性具有相同名字的 bean
• byType :通过 参数的数据类型 自动自动装配, Spring 容器查找 beans 的属性,这
beans XML 配置文件中被设置为 byType 。之后容器试图匹配和装配和该
bean 的属性类型一样的 bean 。如果有多个 bean 符合条件,则抛出错误。
• constructor :这个同 byType 类似,不过是应用于构造函数的参数。如果在
BeanFactory 中不 是恰好有一个 bean 与构造函数参数相同类型,则抛出一个严
重的错误。
• autodetect :如果有默认的构造方法,通过 construct 的方式自动装配,否则使
byType 的 方式自动装配。

七  AOP 是什么?

AOP :全称 Aspect Oriented Programming ,即: 面向切面编程
• AOP Aspect-Oriented Programming ,面向切面编程)能够将那些与业务无关,
却为业务 模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制
等)封装起来,便于减少 系统的重复代码,降低模块间的耦合度,并有利于未
来的可扩展性和可维护性。
• Spring AOP 是基于动态代理的,如果要代理的对象实现了某个接口,那么 Spring
AOP 就会使 用 JDK 动态代理去创建代理对象 ;而对于没有实现接口的对象,就
无法使用 JDK 动态代理,转 而使用 CGlib 动态代理 生成一个被代理对象的子类
来作为代理。 当然也可以使用 AspectJ Spring AOP 中已经集成了 AspectJ
AspectJ 应该算得上是 Java 生态系统中最完整的 AOP 框架了。使用 AOP 之后我
们可以把一些通用功能抽象出来,在需要用到的地方直接使用即可,这样可以
大大简化代码量。我们需要增加新功能也方便,提高了系统的 扩展性。日志功
能、事务管理和权限管理等场景都用到了 AOP

八    AOP 主要用在哪些场景中?

事务管理 比如项目中使用的事务注解 @Transactional
日志管理 创建日志切面
用于全局异常处理拦截
性能统计 将与业务无关的代码,使用 AOP 拦截他们。
缓存使用 @Cacheable @CacheEvict
安全检查
在支付行业往往对安全性要求比较高,我们在保存/接收/发送数据前先要对
数据进行验签/签名/加密等操作,都需要做特殊处理。
比如一个手机号,我们可以通过一个"拦截器"对手机号,身份证号这种敏感
信息做这种特殊处理;

九   SpringBean 的作用域有几种

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 中已经没有了 Portlet

十  Spring 事务管理方式?

编程式事务:在代码中硬编码。
声明式事务:在配置文件中配置 声明式事务又分为:
基于 XML 的声明式事务
基于注解的声明式事务

十一   Spring 事务传播行为有几种?

事务传播行为是为了解决业务层方法之间互相调用的事务问题。当事务方法被另一
个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务
中运行,也可能开启一个新事务,并在自己的事务中运行。在 TransactionDefinition
定义中包括了如下几个表示传播行为的常量:
支持当前事务的情况:
TransactionDefinition.PROPAGATION_REQUIRED( 默认 ) :如果当前存在事务,则加入
该事务;如果当前没有事务,则创建一个新的事务;
TransactionDefinition.PROPAGATION_SUPPORTS :如果当前存在事务,则加入该事务;
如果当前没有事务,则以非事务的方式继续运行;
TransactionDefinition.PROPAGATION_MANDATORY :如果当前存在事务,则加入该
事务;如果当前没有事务,则抛出异常。
不支持当前事务的情况:
TransactionDefinition.PROPAGATION_REQUIRES_NEW :创建一个新的事务,如果当
前存在事务,则把当前事务挂起;
TransactionDefinition.PROPAGATION_NOT_SUPPORTED :以非事务方式运行,如果当
前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_NEVER :以非事务方式运行,如果当前存在事
务,则抛出异常。
其他情况:
TransactionDefinition.PROPAGATION_NESTED :如果当前存在事务,则创建一个事务
作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于
TransactionDefinition.PROPAGATION_REQUIRED

十二   Spring 中的事务隔离级别?

TransactionDefinition 接口中定义了五个表示隔离级别的常量:
• TransactionDefinition.ISOLATION_DEFAULT :使用后端数据库默认的隔离级别,
MySQL 默认采用的 REPEATABLE_READ (可重复读)
隔离级别, Oracle 默认采
用的 READ_COMMITTED (读已提交) 隔离级别;
• TransactionDefinition.ISOLATION_READ_UNCOMMITTED :最低的隔离级别,允许
读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读;
• TransactionDefinition.ISOLATION_READ_COMMITTED :允许读取并发事务已经提
交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生;
• TransactionDefinition.ISOLATION_REPEATABLE_READ :对同一字段的多次读取结
果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复
读,但幻读仍有可能发生;
• TransactionDefinition.ISOLATION_SERIALIZABLE :最高的隔离级别,完全服从
ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产
生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严
重影响程序的性能。通常情况下也不会用到该级别

十三   Spring 中的设计模式有哪些?

工厂模式: Spring 使用工厂模式通过 BeanFactory ApplicationContext 创建
bean 对 象。
单例模式: Spring 中的 bean 默认都是单例的。
代理模式: Spring AOP 功能用到了 JDK 的动态代理和 CGLIB 字节码生成技
术;
模板方法: 用来解决代码重复的问题。比如 RestTemplate jdbcTemplate
JpaTemplate 等以 Template 结尾的对 数据库操作的类,它们就使用到了模板模
式。
观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用。定义对
象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的
对象都会得到通知被制动更新,如 Spring listener 的实现
ApplicationListener
包装器设计模式:
我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要 会去
访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的
数据源。
适配器模式:
Spring AOP 的增强或通知( Advice )使用到了适配器模式、 Spring MVC 中也是用
到了适配器模式适配 Controller

十四     Spring 的常用注解有哪些?(重要)

• @Autowired :用于有值设值方法、非设值方法、构造方法和变量。
• @Component :用于注册所有 bean
• @Repository :用于注册 dao 层的 bean
• @Controller :用于注册控制层的 bean
• @Service :用于注册服务层的 bean
• @Component: 用于实例化对象
• @Value: 简单属性的依赖注入
• @ComponentScan: 组件扫描
• @Configuration: 被此注解标注的类 , 会被 Spring 认为是配置类。 Spring 在启动
的时候会自动扫描并加载所有配置类,然后将配置 类中 bean 放入容器
• @Transactional 此 注解可以标在类上,也可以表在方法上,表示当前类中的方
法 具有事务管理功能

十五   @Resources @Autowired 的区别?

都是用来自动装配的,都可以放在属性的字段上
• @Autowired 通过 byType 的方式实现,而且必须要求这个对象存在!
• @Resource 默认通过 byName 的方式实现,如果找不到名字,则通过 byType
现!如果两个都找不到的情况下,就报错!

以下为重点记忆

黑马

一  .Spring的两大核心是什么?谈一谈你对IOC的理解? 谈一谈你对DI的理解?  谈一谈你对 AOP 的理解?(必会)

1. Spring 的两大核心是:IOC(控制反转)和 AOP(面向切面编程) DI(依赖注入)
2. IOC 的意思是控制反转,是指创建对象的控制权的转移,以前创建对象的主动权和
时机是由自己把控的,而现在这种权力转移到 Spring 容器中,并由容器根据配置文件去创
建实例和管理各个实例之间的依赖关系,对象与对象之间松散耦合,也利于功能的复用。最
直观的表达就是,
IOC 让对象的创建不用去 new 了,可以由 spring 根据我们提供的配置文
件自动生产,我们需要对象的时候,直接从 Spring 容器中获取即可.
Spring 的配置文件中配置了类的字节码位置及信息, 容器生成的时候加载配置文件识
别字节码信息, 通过反射创建类的对象.
Spring 的 IOC 有三种注入方式 :构造器注入, setter 方法注入, 根据注解注入。
3. DI 的意思是依赖注入,和控制反转是同一个概念的不同角度的描述,即应用程序在
运行时依赖 Io c 容器来动态注入对象需要的外部资源。
4. AOP,一般称为面向切面编程,作为面向对象的一种补充,用于将那些与业务无关,
但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被
命名为“切面”(
Aspect). SpringAOP 使用的动态代理,所谓的动态代理就是说 AOP 框
架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个 AOP 对象,这个 AOP
对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。
5. Spring AOP 中的动态代理主要有两种方式,JDK 动态代理和 CGLIB 动态代理:
(1)JDK 动态代理只提供接口代理,不支持类代理,核心 InvocationHandler 接口和
Proxy 类,InvocationHandler 通过 invoke()方法反射来调用目标类中的代码,动态地将
横切逻辑和业务编织在一起,Proxy 利用 InvocationHandler 动态创建一个符合某一接口
的的实例, 生成目标类的代理对象。
(2) 如果代理类没有实现 InvocationHandler 接口,那么 Spring AOP 会选择使用
CGLIB 来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,
可以在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从
而实现 AOP。CGLIB 是通过继承的方式做的动态代理,因此如果某个类被标记为 final,
那么它是无法使用 CGLIB 做动态代理的。

二 .Spring 的生命周期?(高薪常问)

1. 实例化一个 Bean,也就是我们通常说的 new
2. 按照 Spring 上下文对实例化的 Bean 进行配置,也就是 IOC 注入
3. 如果这个 Bean 实现 dao 了 BeanNameAware 接口,会调用它实现的
setBeanName(String beanId)方法,此处传递的是 Spring 配置文件中 Bean 的 ID
4. 如果这个 Bean 实现了 BeanFactoryAware 接口,会调用它实现的 setBeanFactory(),
传递的是 Spring 工厂本身(可以用这个方法获取到其他 Bean)
5. 如果这个 Bean 实现了 ApplicationContextAware 接口,会调用
setApplicationContext(ApplicationContext)方法,传入 Spring 上下文,该方式同样可
以实现步骤 4,但比 4 更好,以为 ApplicationContext 是 BeanFactory 的子接口,有更多
的实现方法
6. 如果这个 Bean 关联了 BeanPostProcessor 接口,将会调用
postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor 经常被
用作是 Bean 内容的更改,并且由于这个是在 Bean 初始化结束时调用 After 方法,也可用
于内存或缓存技术
7. 如果这个 Bean在 Spring 配置文件中配置了 init-method 属性会自动调用其配置的初始
化方法
8. 如果这个 Bean 关联了 BeanPostProcessor 接口,将会调用
postAfterInitialization(Object obj, String s)方法
注意:以上工作完成以后就可以用这个 Bean 了,那这个 Bean 是一个 single 的,所以
一般情况下我们调用同一个 ID 的 Bean 会是在内容地址相同的实例 9. 当 Bean 不再需要时,会经过清理阶段,如果 Bean 实现了 DisposableBean 接口,会
调用其实现的 destroy 方法
10. 最后,如果这个 Bean 的 Spring 配置中配置了 destroy-method 属性,会自动调用其
配置的销毁方法

三    Spring 支持 bean 的作用域有几种吗? 每种作用域是什么样的?(必会)

Spring 支持如下 5 种作用域:
(1)singleton:默认作用域,单例 bean,每个容器中只有一个 bean 的实例。
(2)prototype:每次请求都会为 bean 创建实例。
(3)request:为每一个 request 请求创建一个实例,在请求完成以后,bean 会失效
并被垃圾回收器回收。
(4)session:与 request 范围类似,同一个 session 会话共享一个实例,不同会话
使用不同的实例。
(5)global-session:全局作用域,所有会话共享一个实例。如果想要声明让所有会
话共享的存储变量的话,那么这全局变量需要存储在 global-session 中。

四  BeanFactory 和 ApplicationContext 有什么区别(了解)

BeanFactory:
Spring 最顶层的接口,实现了 Spring 容器的最基础的一些功能, 调用起来比较麻
烦, 一般面向 Spring 自身使用
BeanFactory 在启动的时候不会去实例化 Bean,从容器中拿 Bean 的时候才会去
实例化
ApplicationContext:
是 BeanFactory 的子接口,扩展了其功能, 一般面向程序员身使用
ApplicationContext 在启动的时候就把所有的 Bean 全部实例化了

五    Spring 框架中都用到了哪些设计模式?(必会)

1. 工厂模式:BeanFactory 就是简单工厂模式的体现,用来创建对象的实例
2. 单例模式:Bean 默认为单例模式
3. 代理模式:Spring 的 AOP 功能用到了 JDK 的动态代理和 CGLIB 字节码生成技术
4. 模板方法 :用来解决代码重 复的问题。比如. RestTemplate, JmsTemplate,
JpaTemplate
5. 观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,
所 有 依 赖 于 它 的 对 象 都 会 得 到 通 知 被 制 动 更 新 , 如 Spring 中 listener 的 实 现--ApplicationListener

六    Spring 事务的实现方式和实现原理(必会)

Spring 事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring 是
无法提供事务功能的。真正的数据库层的事务提交和回滚是通过 binlog 或者 redo log 实
现的。
spring 事务实现主要有两种方法
1、编程式,beginTransaction()、commit()、rollback()等事务管理相关的方法
2、声明式,利用注解 Transactional 或者 aop 配置

七   你知道的 Spring 的通知类型有哪些,分别在什么时候执行?(了解)

Spring 的通知类型有四种,分别为:
前置通知[]before]:在切点运行之前执行
后置通知[after-returning]:在切点正常结束之后执行
异常通知[after-throwing]:在切点发生异常的时候执行
最终通知[after]:在切点的最终执行
Spring 还有一种特殊的通知,叫做环绕通知
环绕通知运行程序员以编码的方式自己定义通知的位置, 用于解决其他通知时序
问题

八    Spring 的对象默认是单例的还是多例的? 单例 bean 存不存在线程安全问

题呢?(必会)

1. 在 spring 中的对象默认是单例的,但是也可以配置为多例。
2. 单例 bean 对象对应的类存在可变的成员变量并且其中存在改变这个变量的线程时,
多线程操作该 bean 对象时会出现线程安全问题。
原因是:多线程操作如果改变成员变量,其他线程无法访问该 bean 对象,造成数据混
乱。
解决办法:在 bean 对象中避免定义可变成员变量;
在 bean 对象中定义一个 ThreadLocal 成员变量,将需要的可变成员变量
保存在 ThreadLocal 中。

九  @Resource 和@Autowired 依赖注入的区别是什么? @Qualifier 使用场

景是什么?(了解)

@ Resource
只能放在属性上,表示先按照属性名匹配 IOC 容器中对象 id 给属性注入值若没有
成功,会继续根据当前属性的类型匹配 IOC 容器中同类型对象来注入值
若指定了 name 属性@Resource(name = "对象 id"),则只能按照对象 id 注入值。
@ Autowird
放在属性上:表示先按照类型给属性注入值如果 IOC 容器中存在多个与属性同类
型的对象,则会按照属性名注入值
也可以配合@Qualifier("IOC 容器中对象 id")注解直接按照名称注入值。
放在方法上:表示自动执行当前方法,如果方法有参数,会自动从 IOC 容器中寻
找同类型的对象给参数传值
也可以在参数上添加@Qualifier("IOC 容器中对象 id")注解按照名称寻找对象给
参数传值。
@ Qualifier 使用场景:
@Qualifier("IOC 容器中对象 id")可以配合@Autowird 一起使用, 表示根据指定
的 id 在 Spring 容器中匹配对象

十   Spring 的常用注解(必会)  非常重要

1. @Component(任何层) @Controller @Service @Repository(
dao): 用于
实例化对象
2. @Scope : 设置 Spring 对象的作用域
3. @PostConstruct @PreDestroy : 用于设置 Spring 创建对象在对象创建之后和销
毁之前要执行的方法
4. @Value: 简单属性的依赖注入
5. @Autowired: 对象属性的依赖注入
6. @Qualifier: 要和@Autowired 联合使用,代表在按照类型匹配的基础上,再按照
名称匹配。
7. @Resource 按照属性名称依赖注入
8. @ComponentScan: 组件扫描
9. @Bean: 表在方法上,用于将方法的返回值对象放入容器
10. @PropertySource: 用于引入其它的 properties 配置文件
11. @Import: 在一个配置类中导入其它配置类的内容
12. @Configuration: 被此注解标注的类,会被 Spring 认为是配置类。Spring 在启动
的时候会自动扫描并加载所有配置类,然后将配置
类中 bean 放入容器
13. @Transactional 此注解可以标在类上,也可以表在方法上,表示当前类中的方法
具有事务管理功能

十一    Spring 的事务传播行为(高薪常问)

spring 事务的传播行为说的是,当多个事务同时存在的时候,spring 如何处理这些事
务的行为。
备注(方便记忆): propagation 传播
require 必须的/suppor 支持/mandatory 强制托管/requires-new 需要新建/
not -supported 不支持/never 从不/nested 嵌套的
① PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前
存在事务,就加入该事务,该设置是最常用的设置。
② PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,
如果当前不存在事务,就以非事务执行。
③ PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事
务,如果当前不存在事务,就抛出异常。
④ PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建
新事务。
⑤ PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,
就把当前事务挂起。
⑥ PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
⑦ PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前
没有事务,则按 REQUIRED 属性执行。

十二    Spring 中的隔离级别 (高薪常问)

ISOLATION 隔离的意思
① ISOLATION_DEFAULT:这是个 PlatfromTransactionManager 默认的隔离级别,
使用数据库默认的事务隔离级别。
② ISOLATION_READ_UNCOMMITTED:读未提交,允许另外一个事务可以看到这个
事务未提交的数据。
③ ISOLATION_READ_COMMITTED:读已提交,保证一个事务修改的数据提交后才
能被另一事务读取,而且能看到该事务对已有记录的更新。解决脏读问题
④ ISOLATION_REPEATABLE_READ:可重复读,保证一个事务修改的数据提交后才
能被另一事务读取,但是不能看到该事务对已有记录的更新。行锁
⑤ ISOLATION_SERIALIZABLE:一个事务在执行的过程中完全看不到其他事务对数据
库所做的更新。表锁

动力节点2021

一  . 什么是 Spring 框架?

Spring 是一种轻量级开发框架,旨在提高开发人员的开发效率以及系统的可维护性。

我们一般说 Spring 框架指的都是 Spring Framework,它是很多模块的集合,使用这些模块可以很方便地协助我们进行开发。这些模块是:核心容器、数据访问/集成,、Web、AOP(面向切面编程)、工具、消息和测试模块。比如:核心容器中的 Core 组件是Spring 所有组件的核心,Beans 组件和 Context 组件是实现IOC和依赖注入的基础,AOP组件用来实现面向切面编程。

二  列举一些重要的Spring模块?

Spring Core: 基础,可以说 Spring 其他所有的功能都需要依赖于该类库。主要提供 IoC 依赖注入功能。

Spring AOP :提供了面向切面的编程实现。

Spring JDBC : Java数据库连接。

Spring JMS :Java消息服务。

Spring ORM : 用于支持Hibernate等ORM工具。

Spring Web : 为创建Web应用程序提供支持。

Spring Test : 提供了对 JUnit 和 TestNG 测试的支持。

三  Spring 中的设计模式

工厂设计模式 : Spring使用工厂模式通过 BeanFactory、ApplicationContext 创建 bean 对象。

代理设计模式 : Spring AOP 功能的实现。

单例设计模式 : Spring 中的 Bean 默认都是单例的。

模板方法模式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。

包装器设计模式 : 我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。

适配器模式 :Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配Controller。

四    什么是Ioc及其优点

IoC(Inverse of Control:控制反转)是一种设计思想,就是 将原本在程序中手动创建对象的控制权,交由Spring框架来管理。IoC 容器是 Spring 用来实现 IoC 的载体, IoC 容器实际上就是个Map(key,value),Map 中存放的是各种对象。

将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注入。这样可以很大程度上简化应用的开发,把应用从复杂的依赖关系中解放出来。 IoC 容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。

在实际项目中一个 Service 类可能有几百甚至上千个类作为它的底层,假如我们需要实例化这个 Service,你可能要每次都要搞清这个 Service 所有底层类的构造函数,这可能会把人逼疯。如果利用 IoC 的话,你只需要配置好,然后在需要的地方引用就行了,这大大增加了项目的可维护性且降低了开发难度。

Spring 时代我们一般通过 XML 文件来配置 Bean,后来开发人员觉得 XML 文件来配置不太好,于是 SpringBoot 注解配置就慢慢开始流行起来。

五  IOC容器的初始化过程

IOC容器的初始化主要包括Resource定位,载入和注册三个步骤,接下来我们依次介绍。

Resource资源定位:

Resouce定位是指BeanDefinition的资源定位,也就是IOC容器找数据的过程。Spring中使用外部资源来描述一个Bean对象,IOC容器第一步就是需要定位Resource外部资源。由ResourceLoader通过统一的Resource接口来完成定位。

BeanDefinition的载入:

载入过程就是把定义好的Bean表示成IOC容器内部的数据结构,即BeanDefinition。在配置文件中每一个Bean都对应着一个BeanDefinition对象。

通过BeanDefinitionReader读取,解析Resource定位的资源,将用户定义好的Bean表示成IOC容器的内部数据结构BeanDefinition。

在IOC容器内部维护着一个BeanDefinitionMap的数据结构,通过BeanDefinitionMap,IOC容器可以对Bean进行更好的管理。

BeanDefinition的注册:

注册是将前面的BeanDefition保存到Map中的过程,通过BeanDefinitionRegistry接口来实现注册。

六      Spring 提供了多种依赖注入的方式

Set 注入

构造器注入

接口注入

注解注入

Spring启动时读取应用程序提供的Bean 配置信息,并在Spring 容器中生成一份相应的Bean 配置注册表,然后根据这张注册表实例化Bean,装配好Bean 之间的依赖关系,为上层应用提供准备就绪的运行环境。其中Bean 缓存池为HashMap 实现

七   Spring中,如何给对象的属性赋值?

1. 通过构造函数

2. 通过set方法给属性注入值

3. 自动装配

byName 通过参数名自动装配,如果一个bean的name 和另外一个bean的  property 相同就自动装配。

byType   通过参数的数据类型自动自动装配,如果一个bean的数据类型和另 外一个bean的property属性的数据类型兼容,就自动装配必须确保 该类型在IOC容器中只有一个对象;否则报错。

     4.注解

使用注解步骤:

1)先引入context名称空间

xmlns:context="http://www.springframework.org/schema/context"

2)开启注解扫描

<context:component-scan base-package="cn.itcast.e_anno2"></context:component-scan>

3)使用注解

通过注解的方式,把对象加入ioc容器。

    创建对象以及处理对象依赖关系,相关的注解:

@Component   指定把一个对象加入IOC容器

@Repository   作用同@Component; 在持久层使用

@Service      作用同@Component; 在业务逻辑层使用

@Controller    作用同@Component; 在控制层使用

@Resource或@Autowired     属性注入

@Qualifier指定注入bean的名称,防止在容器中有重名的bean

总结:

1) 使用注解,可以简化配置,且可以把对象加入IOC容器,及处理依赖关系(DI)
2) 注解可以和XML配置一起使用。

     3) @Resource的作用相当于@Autowired,只不过@Autowired按byType自动 注入,而 @Resource默认按 byName自动注入

 八  bean对象创建的细节

1) 对象创建: 单例/多例

scope="singleton", 默认值, 即 默认是单例 【service/dao/工具类】

scope="prototype", 多例; 【Action对象】

Spring的单例bean不是线程安全的(可以用局部变量使线程安全)

2) 什么时候创建?

scope="prototype"  在用到对象的时候,才创建对象。

scope="singleton"  在启动(容器初始化之前), 就已经创建了bean,且整个应用只有一个。

3)是否延迟创建

lazy-init="false"  默认为false,  不延迟创建,即在启动时候就创建对象

lazy-init="true"   延迟初始化, 在用到对象的时候才创建对象(只对单例有效)

4) 创建对象之后,初始化/销毁

init-method="init_user" 【对应对象的init_user方法,对象创建之后执行】 destroy-method="destroy_user"  【在调用容器对象的destriy方法时候执行,(容器用实现类)】

九   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 已经没有了。Portlet是能够生成语义代码(例如:HTML)片段的小型Java Web插件。它们基于 portlet容器,可以像servlet一样处理HTTP请求。但是,与 servlet 不同,每个 portlet 都 有不同的会话

十  Bean的生命周期

 

Bean 容器找到配置文件中 Spring Bean 的定义。

Bean 容器利用 Java Reflection API 创建一个Bean的实例。

如果涉及到一些属性值利用 set()方法设置一些属性值。

如果 Bean 实现了 BeanNameAware 接口,调用 setBeanName()方法,传入Bean的名字。

如果 Bean 实现了 BeanClassLoaderAware 接口,调用 setBeanClassLoader()方法,传入 ClassLoader对象的实例。

与上面的类似,如果实现了其他 *.Aware接口,就调用相应的方法。

如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行postProcessBeforeInitialization() 方法

如果Bean实现了InitializingBean接口,执行afterPropertiesSet()方法。

如果 Bean 在配置文件中的定义包含 init-method 属性,执行指定的方法。

如果有和加载这个 Bean的 Spring 容器相关的 BeanPostProcessor 对象,执行postProcessAfterInitialization() 方法

当要销毁 Bean 的时候,如果 Bean 实现了 DisposableBean 接口,执行 destroy() 方法。

当要销毁 Bean 的时候,如果 Bean 在配置文件中的定义包含 destroy-method 属性,执行指定的方法。

十 一  BeanFactory和ApplicationContext的区别?

BeanFactory是Spring里面最顶层的接口,包含了各种Bean的定义,读取Bean配置文档,管理Bean的加载、实例化,控制Bean的生命周期,维护Bean之间的依赖关系。

ApplicationContext接口是BeanFactory的派生,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能

十二    AOP

答: AOP,面向切面编程是指当需要在某一个方法之前或者之后做一些额外的操作,比如说日志记录,权限判断,异常统计等,可以利用AOP将功能代码从业务逻辑代码中分离出来。

Spring中的AOP主要有两种实现方式:

使用JDK动态代理实现,使用java.lang.reflection.Proxy类来处理

使用cglib来实现

两种实现方式的不同之处:

JDK动态代理,只能对实现了接口的类生成代理,而不是针对类,该目标类型实现的接口都将被代理。原理是通过在运行期间创建一个接口的实现类来完成对目标对象的代理。

cglib主要针对类实现代理,对是否实现接口无要求。原理是对指定的类生成一个子类,覆盖其中的方法,因为是继承,所以被代理的类或方法不可以声明为final类型。

Spring AOP对这两种代理方式的选择:

如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP,也可以强制使用cglib实现AOP;

如果目标对象没有实现接口,必须采用cglib库,Spring会自动在JDK动态代理和cglib之间转换。

 

十三    事务

Spring支持编程式事务(不用)和声明式事务两种方式:

编程式事务管理:使用TransactionTemplate实现。

声明式事务管理:建立在AOP之上的。其本质是通过AOP功能,对方法前后进行拦截,将事务处理的功能编织到拦截的方法中,也就是在目标方法开始之前加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。

声明式事务的优点:

就是不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明或通过@Transactional注解的方式,便可以将事务规则应用到业务逻辑中。

事务选择:

声明式事务管理要优于编程式事务管理,这正是Spring倡导的非侵入式的开发方式,使业务代码不受污染,只要加上注解就可以获得完全的事务支持。唯一不足之处是声明式事务的最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。

当多个Spring事务存在的时候,Spring定义了下边的7个传播行为来处理这些事务行为:

PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。

PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。

spring事务对于查询的find()是只读,对保存save()是读写?

 

 

 

 

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值