ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

4.Spring面试题

2021-10-02 11:02:48  阅读:113  来源: 互联网

标签:面试题 Spring 事务 bean 切面 注解 方法


4.Spring面试题

1.什么是控制反转IOC?什么是依赖注入DI?

IOC就是控制反转,是将组件对象的控制权由程序代码本身交给外部容器管理,所以叫控制反转。
控制反转的作用是:创建对象,维护对象的依赖关系,实现了解耦,降低了维护成本。
DI:我们使用Spring容器的时候,容器通过调用set方法或者是构造器来建立对象之间的依赖关系。控制反转是目标,依赖注入是我们实现控制反转的一种手段。

2.SpringIOC创建bean对象的生命周期

bean的生命周期初步分为四个阶段Bean的实例化阶段,Bean的设置属性阶段,Bean的初始化阶段,Bean的销毁阶段
1.Bean容器利用反射机制对bean进行实例化
2.Bean容器为实例化的bean设置属性值
3.如果bean实现了BeanNameAware接口,则执行setBeanName方法
4.如果bean实现了BeanClassLoaderAware接口,则执行setBeanClassLoader方法
5.如果bean实现了BeanFactoryAware接口,则执行setBeanFactory方法
6.如果bean实现了ApplicationContextAware接口,则执行setApplicationContext方法
7.如果加载了BeanPostProcessor相关实现类,则执行postProcessBeforeInitialization方法
8.如果bean实现了InitializationBean接口,则执行afterPropertiesSet方法
9.如果bean定义了初始化方法(配置文件配置init-method或者添加注解@PostConstruct),则执行定义的初始化方法
10.如果加载了BeanPostProcessor相关实现类,则执行postProcessAfterInitialization方法
11.当要销毁这个bean时,如果Bean实现了DisposableBean接口,则执行destroy方法
12.如果bean自定义了销毁方法(配置文件配置destroy-method或者添加注解@PreDestory),则执行定义的销毁方法
参考文章

3.什么是Spring的AOP?

AOP是面向切面编程,能够将那些与业务没有关系,各个模块却都需要共同调用的代码封装起来,例如事务处理,日志管理,权限控制等,可以减少系统的重复代码,降低耦合度,更利于维护和扩展。
SpringAOP是基于动态代理实现的,如果代理对象实现了某个接口,那么SpringAOP会使用JDK的proxy去创建代理对象,如果没有实现接口,就用Cglib生成一个被代理对象的子类。

4.说下SpringAOP里面的几个名词

1.JointPoint连接点:类里面哪些方法可以被增强,这些方法叫连接点。
2.PointCut切入点:实际被真正增强的方法称为切入点
3.Advice通知:实际增强逻辑部分称为通知,分为前置通知,后置通知,异常通知,最终通知,环绕通知
4.Aspect切面:AOP核心就是切面,它将多个类的通用行为封装成可重用的模块,该模块含有一组API提供横切功能。比如,一个日志模块可以被称作日志的AOP切面。根据需求的不同,一个应用程序可以有若干切面。在Spring AOP中,切面通过带有@Aspect注解的类实现。
5.Target目标对象:被一个切面或者多个切面所通知的对象。通常是一个代理对象。(springaop中一定是代理对象,因为AOP是通过动态代理实现)
6.weaving:织入:指把增强应用到目标对象创建代理对象的过程
7.introduction引入:引入是一种特殊的通知,在不修改代码前提下,spring可以在运行期为类动态添加方法和属性
在这里插入图片描述

5.什么是Spring的自动装配?spring自动装配bean有哪些方式

在spring中,对象无需自己查找和创建所关联的其它对象,由容器负责把所关联的对象引用给各个对象,使用autowire来配置自动装配模式
在Spring中xml配置一共有四种自动装配

  • no:默认的方式是不进行自动装配,需要通过手动设置ref属性装配
  • byName:根据属性名称注入,类属性的名称要跟bean的id值一致,需要有setter方法才能注入
  • byType:根据属性类型注入,需要有setter方法才能注入
  • constructor: 利用构造函数进行装配,不需要setter方法,需要添加参数带关联对象的构造方法

6.Spring中的bean的初始化方式有几种?有什么区别?

Spring中给bean初始化的方式有有两种
一种是实现InitializationBean接口,重写afterPropertiesSet方法,初始化bean的时候会执行该方法
一种是定义初始化方法,使用配置文件配置init-method,或者给方法添加@PostConstruct注解
如果两种同时使用,先调用afterPropertiesSet方法,后调用自己定义的初始化方法
前者和Spring耦合程度更高但效率高,后者解除了和Spring之间的耦合但是效率低
参考文档

7.@Autowired和@Resource的匹配规则

@Autowired注解可适用于成员变量、setter方法和构造函数
@Autowired注解优先使用根据类型进行标注装配
@Autowired注解配置使用@Qualifier可完成按照名称进行装配
@Autowired注解默认要求依赖对象必须存在,如果要允许null值,则设置它的required属性为false
@Resource注解默认按照名字进行装配,找不到名字匹配的bean时才会按照类型进行装配,但如果使用name属性指定bean的名称,则只会按照名字进行装配。

8.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("io.github.dunwu.spring.Apple");
        if(f!=null){
            f.eat();
        }
    }
}

8.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 来实现。

  • @Bean 注解扮演与 元素相同的角色。
  • @Configuration 类允许通过简单地调用同一个类中的其他 @Bean 方法来定义 bean 间依赖关系。
    例如:
@Configuration
public class StudentConfig {
    @Bean
    public StudentBean myStudent() {
        return new StudentBean();
    }
}

9.Spring开启<context:annotation-config>和<context:component-scan>的区别

<context:annotation-config>是用于激活那些已经在spring容器里注册过的bean(无论是xml方式还是通过package scanning)
<context:component-scan>除了具有<context:annotation-config>的功能以外,还会自动将package包下带有@Component,@Service @Controller等等注解的对象注册到Spring容器
参考文章

10.Spring中有多少个模块,它们分别是什么

Spring核心容器(Core Container)-该层是Spring框架的核心

  • spring core
  • spring bean
  • spring context
  • SpEL

数据访问/集成-该层提供与数据库交互的支持

  • JDBC
  • ORM
  • OXM
  • JMS
  • Transaction

Web-该层提供了创建web应用程序的支持

  • Web
  • Web-Socket
  • Web-Servlet
  • Web-Portlet

AOP 该层支持面向切面编程
Aspects 该层提供了AspectJ的集成提供支持
Test 该层为使用Junit和TestNG进行测试提供支持
Instrumentation – 该层为类检测和类加载器实现提供支持。
Messageing 该模块为 STOMP 提供支持
在这里插入图片描述

11.SpringAOP中有哪些类型的通知

前置通知@before
后置通知@AfterReturning
异常通知@AfterThrowing
最终通知@After
环绕通知@Around
五大通知执行顺序(spring5.0)
环绕前置→前置通知→目标方法执行→后置通知/异常通知→最终通知→环绕后置/环绕异常→环绕最终
多个切面的通知顺序
切面1环绕前置→切面1@Before→切面2环绕前置→切面2@Before→目标方法执行→切面2@AfterReturning→切面2@After→切面2环绕返回→切面2环绕最终→切面1@AfterReturning→切面1@After→切面1环绕返回→切面1环绕最终
在这里插入图片描述

12.SpringAop的操作方法(纯注解)

创建配置类开启AOP
在这里插入图片描述
创建类
在这里插入图片描述
创建增强类
在这里插入图片描述

13.声明式事务配置的三种方式

xml+事务注解(推荐)
1.跟完全注解区别就是数据源,jdbcTemplate,事务管理器,开启事务的注解用xml配置
在这里插入图片描述
完全xml声明式事务管理
1.不需要开启@Transactional注解
在这里插入图片描述
完全注解声明式事务管理
1.创建配置类
在这里插入图片描述
2.给方法添加@Transactional 也可以添加到类上面表示所有方法都添加事务
在这里插入图片描述
3.测试
在这里插入图片描述

14.ApplicationContext和BeanFactory的区别

BeanFactory:
BeanFactory是spring中比较原始,比较古老的Factory。因为比较古老,所以BeanFactory无法支持spring插件,例如:AOP、Web应用等功能。

ApplicationContext:
ApplicationContext是BeanFactory的子类,因为古老的BeanFactory无法满足不断更新的spring的需求,于是ApplicationContext就基本上代替了BeanFactory的工作,以一种更面向框架的工作方式以及对上下文进行分层和实现继承,并在这个基础上对功能进行扩展:

  1. MessageSource, 提供国际化的消息访问
  2. 对web应用的支持
  3. 强大的事件机制
  4. Bean的自动装配
  5. 各种不同应用层的Context实现

在这里插入图片描述

区别总结

  • 当我们使用ApplicationContext去获取bean的时候,在加载XXX.xml的时候,会创建所有的配置bean。好处是可以预先加载,坏处是浪费内存。
  • 重点:当我们使用BeanFactory去获取Bean的时候,我们只是实例化了该容器,而该容器中的bean并没有被实例化。当我们getBean的时候,才会实时实例化该bean对象(懒加载)。好处是节约内存,坏处是速度比较慢。多用于移动设备的开发。
  • 没有特殊要求的情况下,应该使用ApplicationContext完成。因为BeanFactory能完成的事情,ApplicationContext都能完成,并且提供了更多接近现在开发的功能。

15.Spring框架中的单例bean是线程安全的吗

spring单例的bean是否是线程安全的,主要看bean有没有全局变量,如果只有局部变量那就是线程安全的
由于大部分的Spring bean比如Service类和Dao类,它们都没有实例变量,无法保存数据,所以是无状态的,就是线程安全的。
有实例变量的对象,是有状态的对象,由于资源被多个线程共享是非线程安全的。
对于有状态的对象,最浅显的解决办法就是将多态bean的作用域由“singleton”变更为“prototype”。

一、局部变量,不存在线程安全问题,因为每个请求都是一个线程请求,局部变量都在线程内不共享(这里指的是单例bean是线程安全的,但是局部变量不一定是线程安全的)
在这里插入图片描述
二、全局变量,存在线程安全问题,全局变量是共享数据
在这里插入图片描述

16.InitializingBean接口afterPropertiesSet(),DisposableBean接口的destroy()和自定义的init-method,destroy-method的区别

InitializingBean接口、DisposableBean接口底层使用类型强转.方法名()进行直接方法调用,init-method、destory-method底层使用反射,前者和Spring耦合程度更高但效率高,后者解除了和Spring之间的耦合但是效率低,使用哪个看个人喜好
在这里插入图片描述
(1)实现InitializingBean,DisposableBean接口
在这里插入图片描述
(2)xml配置文件定义init-mehod,destroy-method
在这里插入图片描述
也可以使用注解的方式自定义init-method(@PostConstruct)和destory-method(@PreDestroy),需要开启context:annotation-config
在这里插入图片描述

17.Spring中如何注入一个java集合

类型用于注入一列值,允许有相同的值。
类型用于注入一组值,不允许有相同的值。
类型用于注入一组键值对,键和值都可以为任意类型。
类型用于注入一组键值对,键和值都只能为String类型。

18.Spring支持的事务管理类型,你更倾向用那种事务管理类型?

Spring支持两种类型的事务管理:

**编程式事务管理:**这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。
**声明式事务管理:**这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。

大多数Spring框架的用户选择声明式事务管理,因为它对应用代码的影响最小,因此更符合一个无侵入的轻量级容器的思想。声明式事务管理要优于编程式事务管理,虽然比编程式事务管理(这种方式允许你通过代码控制事务)少了一点灵活性。

19.Spring中@Transactional里的事务的隔离级别和事务传播特性

在这里插入图片描述
Spring中提供了5种事务的隔离级别
DEFAULT:默认使用的是数据库的隔离级别
READ_UNCOMMITTED: 最低的隔离级别,允许读取事务未提交的数据,可能发生脏读,不可重复读,幻读问题
READ_COMMITTED:只能读取事务提交后的数据,能够解决脏读问题,不能解决不可重复读,幻读问题
REPEATABLE_READ:当一个事务读取一个数据时会对其进行加锁处理,防止其他事务对数据进行修改,如果这个事务不结束,别的事务就不可以更改这个数据,除非这个数据是事务自身修改的。可以解决脏读,不可重复读的问题,不能解决幻读。
Serlalizable:最高的隔离级别,完全服从ACID的隔离级别,所有的事务依次逐个执行,不可能相互干扰。可以解决脏读,不可重复读,幻读问题。

事务的传播特性就是多个事务方法相互调用时,事务如何在这些方法间传播。
Propagation.REQUIRED:默认的传播特性,如果调用者存在事务那就共用一个事务,否则自己会创建一个事务
Propagation.REQUIRES_NEW:无论调用者存不存在事务,都会新建一个事务。如果调用者存在事务就把当前事务挂起(等待新的事务执行完毕后,当前事务才继续执行)

Propagation.REQUIRES_SUPPORTS:如果调用者存在事务那就共用一个事务,如果当前没有事务也可以以非事务方式执行
Propagation.NOT_SUPPORTED:如论当前存不存在事务,都不会新建事务,只能以非事务方式执行。如果调用者存在事务就把当前事务挂起

Propagation.MANDATORY:必须使用当前事务,如果调用者不存在事务就抛出异常
Propagation.NEVER:如果当前有事务,就抛出异常。否则以非事务的方式执行

Propagation.NESTED:如果调用者存在事务,就在嵌套事务内执行,否则就新建一个事务.NESTED的原理就是申明一个嵌套事务来使用保存点功能,达到事务部分回滚的目的。
主事务和嵌套事务属于同一个事务
嵌套事务出错回滚不会影响到主事务
主事务回滚会将嵌套事务一起回滚
参考文档1 参考文档2

标签:面试题,Spring,事务,bean,切面,注解,方法
来源: https://blog.csdn.net/weixin_53509920/article/details/120583778

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有