Spring面试题(二)

news2024/12/29 3:16:11

一、老杜讲解Spring6整理

1. Spring有哪几大模块?

2. IoC控制反转的实现是依赖注入,set依赖注入的原理是什么?

3. 自动装配有哪几种?它的原理是基于构造注入还是基于set注入?

4. Spring容器中的Bean是单例还是多例?

  • Spring的IoC容器中,默认情况下,Bean对象是单例的。默认情况下,Bean对象的创建是在初始化Spring上下文的时候就完成的。
  • 可以在bean标签中指定scope属性的值为:prototype,这样Spring会在每一次执行getBean()方法的时候创建Bean对象,调用几次则创建几次。
  • scope属性的值不止两个,它一共包括8个选项。

5. 工厂模式有几种?工厂方法模式的角色有哪些?好处是什么?

6. Spring中Bean的实例化方式?

7. BeanFactory和FactoryBean的区别?

8. 你知道Bean的生命周期吗?7步中的那个类叫什么?

9. Spring如何管理Bean的生命周期?

Java对象的实例化和初始化的区别:

  • 实例化:创建一个对象的过程,就是使用new关键字调用类的构造函数来生成一个新的实例。
  • 初始化:给对象的成员变量赋予初始值的过程,包括字段的默认初始化、显式初始化,及构造函数中的初始化操作。

10. 自己new的对象Spring可以管理吗?

可以。自己创建默认可列表Bean工厂对象(DefaultListableBeanFactory),并在其中注册。

11. Spring的循环依赖如何解决?

这个视频说的超级明白:【Java面试】Spring的缓存有什么用? 能不能拿掉二级缓存?_哔哩哔哩_bilibili

结论:Spring只能解决setter方法注入的单例bean之间的循环依赖。Spring解决循环依赖的机理是三级缓存,代码存在于DefaultSingletonBeanRegistry类中。三级缓存,本质上是三个Map集合。

  • singletonObjects:一级缓存,单例对象的缓存,key存储bean名称,value存储已经初始化完成的Bean对象;已经完成了bean的所有流程,即实例化、注入、初始化完成的bean实例,并放进了单列池中了。
  • earlySingletonObjects:二级缓存,早期单例对象的缓存,key存储bean名称,value存储早期的Bean对象;保存所有早期创建的Bean对象,这个Bean还没有完成依赖注入,但已经提前完成了AOP增强。
  • singletonFactories:三级缓存,单例工厂缓存,key存储bean名称,value存储该Bean对应的ObjectFactory对象。它是singletonBean的生产工厂,即创建单列bean的工厂。

Spring为什么可以解决set + singleton模式下循环依赖?

根本的原因在于:这种方式可以做到将“实例化Bean”和“给Bean属性赋值”这两个动作分开去完成。

实例化Bean的时候:调用无参数构造方法来完成。此时可以先不给属性赋值,可以提前将该Bean对象“曝光”给外界。

给Bean属性赋值的时候:调用setter方法来完成。

两个步骤是完全可以分离开去完成的,并且这两步不要求在同一个时间点上完成。

也就是说,Bean都是单例的,我们可以先把所有的单例Bean实例化出来,放到一个集合当中(我们可以称之为缓存),所有的单例Bean全部实例化完成之后,以后我们再慢慢的调用setter方法给属性赋值。这样就解决了循环依赖的问题。

Spring 循环依赖解决方案_spring循环依赖及解决方式-CSDN博客

spring循环依赖及解决方法_spring循环依赖及解决方式-CSDN博客

为什么需要二级缓存?(来源于上面链接的文章)

如果出现循环依赖+aop时,多个地方注入这个动态代理对象需要保证都是同一个对象,而三级缓存中的取出来的动态代理对象每次都是新对象,地址值不一样。

为什么需要第三级缓存?(来源于上面链接的文章)

解决如果出现循环依赖,判断是否需要提前进行aop等操作。

12. 代码层面如何解决Spring的循环依赖问题?

首先,可以避免这样的设计,在上面的链接文章中也有提到,更多内容可查看上面文章。

如何理解Spring的循环依赖问题?以及解决方案?(提示:AI自动生成,仅供参考)

Spring 的循环依赖问题通常发生在以下情况:

  1. 构造函数注入造成的循环依赖:Spring 无法解析循环依赖的对象,因为每个Bean在创建时都依赖另外的Bean。

  2. Setter方法注入引起的循环依赖:Spring 可以解决大多数的循环依赖,因为它可以先提前暴露一个代理对象,然后再注入依赖。

解决方案:

  1. 构造函数注入的循环依赖:尽量避免在构造函数中直接使用@Autowired注解,改用@Autowired与@Qualifier注解结合使用,或者使用Java配置类(@Configuration)中的@Bean方法来明确指定依赖关系。

  2. Setter方法注入的循环依赖:确保你的Bean有一个无参构造函数,并且所有依赖的Bean都标注了@Autowired。

示例代码:

// 使用Java配置类解决循环依赖
@Configuration
public class AppConfig {

    @Bean
    public A aBean() {
        return new A(bBean()); // A依赖B,但B在此之前已经创建
    }

    @Bean
    public B bBean() {
        return new B(aBean()); // B依赖A,但A在此之前已经创建
    }
}

// 使用Setter方法解决循环依赖
public class A {
    private B b;
    public A() {}

    @Autowired
    public void setB(B b) {
        this.b = b;
    }
}

public class B {
    private A a;
    public B() {}

    @Autowired
    public void setA(A a) {
        this.a = a;
    }
}

在配置类中,通过@Bean方法间接创建Bean,Spring能够处理好这种间接依赖,从而避免直接循环依赖。在普通的Bean类中,通过@Autowired注解的Setter方法提供依赖注入,Spring能够处理好这种依赖注入,从而避免直接循环依赖。

13. 动态代理技术了解吗?项目中有用到吗?CGLIB动态代理和jdk动态代理的区别?

  • JDK动态代理:只能代理接口,即目标类是至少一个接口的实现类时,才能用;
  • CGLIB动态代理:既可以代理接口,又可以代理类。底层采用继承的方式实现。所以被代理的目标类不能使用final修饰。

14. AOP你了解多少?

  • 底层是动态代理。Spring的AOP使用的动态代理是:JDK动态代理 + CGLIB动态代理技术。Spring在这两种动态代理中灵活切换,如果是代理接口,会默认使用JDK动态代理,如果要代理某个类,这个类没有实现接口,就会切换使用CGLIB。当然,你也可以强制通过一些配置让Spring只使用CGLIB。
  • 面向切面编程的7大术语是什么?
  • 通知有哪几种类型?
  • 切点表达式的语法格式?

切点表达式如何和注解配合使用?

切点表达式可以与注解配合使用来更精确地定位需要拦截的代码点。下面是一个简化的例子:

        1) 首先,创建一个自定义注解,比如@Loggable,用于标记需要记录日志的方法:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Loggable {
}

        2)然后,在需要记录日志的方法上使用这个注解:

public class SomeService {

    @Loggable
    public void doSomethingImportant() {
        // 执行重要操作
    }
}

        3)接下来,编写一个切面(Aspect),使用@Around注解和切点表达式来匹配标注了@Loggable的方法:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {

    @Around("@annotation(Loggable)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = joinPoint.proceed(); // 执行原始方法
        long elapsedTime = System.currentTimeMillis() - start;

        String className = joinPoint.getSignature().getDeclaringTypeName();
        String methodName = joinPoint.getSignature().getName();

        System.out.println(className + "." + methodName + " executed in " + elapsedTime + "ms");

        return result;
    }
}

在这个例子中,@Around("@annotation(Loggable)")切点表达式表示匹配所有带有@Loggable注解的方法。当这些方法被调用时,logExecutionTime方法将会在实际方法执行前后进行日志记录。

多个切点还可以这样写“||” ,如下:

package com.powernode.spring6.biz;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class SecurityAspect {

    @Pointcut("execution(* com.powernode.spring6.biz..save*(..))")
    public void savePointcut(){}

    @Pointcut("execution(* com.powernode.spring6.biz..delete*(..))")
    public void deletePointcut(){}

    @Pointcut("execution(* com.powernode.spring6.biz..modify*(..))")
    public void modifyPointcut(){}

    @Before("savePointcut() || deletePointcut() || modifyPointcut()")
    public void beforeAdivce(JoinPoint joinpoint){
        System.out.println("XXX操作员正在操作"+joinpoint.getSignature().getName()+"方法");
    }
}

15. Spring事务

        1)Spring实现事务有哪些方式?

        2)事务的接口、实现类是什么?

        3)事务属性有哪些?

        4)事务的传播行为具体是什么?

        我自己写的:Spring事务介绍-CSDN博客

        5)事务的隔离级别?

2. Spring中如何配置事务管理器?

在Spring中配置事务管理器通常涉及以下几个步骤:

1. 引入依赖:确保你的项目包含了Spring的事务管理相关的库,比如对于Maven项目,在pom.xml文件中添加以下依赖(以Spring Boot为例):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

对于没有使用Spring Boot的项目,你需要手动添加相应的Spring JDBC、Hibernate等依赖。

2. 配置数据源:在Spring Boot中,通过application.properties或application.yml配置数据库连接信息,例如:

# application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/testdb
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=update

如果是XML配置方式,你需要在context.xml或类似配置文件中添加<bean>定义数据源。

3. 选择并配置事务管理器:基于不同的持久化技术,选择合适的事务管理器。如果使用JPA/Hibernate,Spring Boot会自动配置PlatformTransactionManager;若使用JDBC,可以手动配置DataSourceTransactionManager

@Configuration
@EnableTransactionManagement
public class TransactionConfig {

    @Autowired
    private DataSource dataSource;

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource);
    }
}

在XML配置中,你会创建一个<tx:annotation-driven/>标签来启用基于注解的事务管理。

4. 标注事务方法:在需要进行事务管理的Service层或DAO层方法上使用@Transactional注解。

完成以上步骤后,Spring就会为你提供事务管理功能了。

@Repository和@Mapper注解的区别

@Repository@Mapper这两个注解在不同的框架中起作用:

  1. @Repository

    • 它是Spring框架的一部分,主要用于标记 DAO(数据访问对象)层的类。
    • 当Spring遇到这个注解的类时,它会自动处理异常并创建bean,使得你可以使用@Autowired注入这个bean到其他依赖它的组件中。
    • @Repository有助于异常透明化,意味着DAO层抛出的数据库异常会被转换为Spring的数据访问异常。
  2. @Mapper

    • 这是MyBatis框架中的注解,它用于标记接口,表示这个接口是一个映射器接口。
    • MyBatis-Spring桥接库允许你在接口上使用@Mapper,这样Spring就能找到对应的Mapper接口实例。
    • 如果没有@Mapper注解,但有@Repository,并且接口继承了MyBatis的Mapper接口,通常也能够工作,因为Spring会把它当作一个bean处理。

区别:

  1. @Repository是Spring框架的注解,而@Mapper属于MyBatis。
  2. @Repository用于标记整个DAO类,而@Mapper用于标记映射器接口。
  3. 使用@Repository不需要额外配置,即可与Spring一起工作,而@Mapper需要配合@MapperScan在Spring Boot的启动类上,或者配置XML来扫描和启用。
  4. @Repository@Autowired一起使用时,Spring会自动创建bean,避免了编译时的警告或错误。
  5. @Mapper接口下的方法可以直接写SQL片段,而@Repository通常配合的是具体实现类,SQL可能写在XML文件中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1559479.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mybatis-Plus分页查询时碰到`total`有值但`records`为空

个人原因&#xff1a;Mybatis-Plus分页插件设置了maxLimit单页条数 // 分页插件配置 PaginationInnerInterceptor paginationInnerInterceptor new PaginationInnerInterceptor(DbType.MYSQL); paginationInnerInterceptor.setMaxLimit(200L); // 单页分页条数限制(默认无限…

博客页面---前端

目录 主页 HTML CSS 文章详细页面 HTML CSS 登录页面 HTML CSS 文章编辑页 HTML CSS 这只是前端的页面组成&#xff0c;还没有接入后端&#xff0c;并不是完全体 主页 HTML <!DOCTYPE html> <!-- <html lang"en"> --> <head>&…

【PSINS工具箱】基于工具箱,自己设计的轨迹,并生成IMU数据和三维视图(完整代码)

完整代码 在有工具箱的情况下&#xff0c;直接运行代码&#xff0c;即可 % 基于PSINS工具箱的三维轨迹生成、三维图像绘制与IMU数据生成 % date:2024-2-13 % Evand&#xff08;evandworldqq.com&#xff09; % Ver1 clear;clc;close all; glvs ts 0.1; % sampling int…

Redis(十九)缓存过期淘汰策略

文章目录 面试题内存满怎么办写入的数据如何删除的&#xff08;删除策略&#xff09;立即删除惰性删除上面两种方案都走极端 缓存淘汰策略配置文件LRU和LFU区别有哪些如何配置、修改 redis缓存淘汰策略配置性能建议 面试题 生产上你们的redis内存设置多少?如何配置、修改redi…

动态规划-最长回文子串

动态规划-最长回文子串 原题描述解答中心移动思想代码实现复杂度分析时间复杂度空间复杂度 动态规划思想代码实现复杂度分析时间复杂度空间复杂度 突然觉得很有必要将学过的内容记录下来&#xff0c;这样后续在需要用到的时候就可以避免从头进行学习&#xff0c;而去看自己之前…

【Threejs基础教程-光影篇】5.2 Threejs 阴影系统

5.2 Threejs阴影系统 学习ThreeJS的捷径在用光影系统之前threejs是实时光影web端目前没有优质的实时光影实时光影会大幅增加渲染压力没有独显的电脑不建议添加实时光影 阴影配置什么样的灯光可以产生阴影什么样的物体可以产生阴影和接受阴影注意开启阴影渲染灵活运用阴影 平行光…

【Linux】普通用户提升权限

概述 在Linux环境下&#xff0c;给普通用户提权的方式&#xff0c;su与sudo命令&#xff0c;su是将一个普通用户登录为root&#xff0c;而sudo则是将普通用户短暂提升权限 普通用户使用$ root使用# 使用su提升权限 如果我们使用su将用户提升为root&#xff0c;此时需要输入…

计算机网络:数据链路层 - 封装成帧 透明传输 差错检测

计算机网络&#xff1a;数据链路层 - 封装成帧 & 透明传输 & 差错检测 数据链路层概述封装成帧透明传输差错检测 数据链路层概述 从数据链路层来看&#xff0c;主机 H1 到 H2 的通信可以看成是在四段不同的链路上的通信组成的&#xff0c;所谓链路就是从一个节点到相邻…

回溯算法|39.组合总和

力扣题目链接 class Solution { private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {if (sum > target) {return;}if (sum target) {result.push_back…

CISP考前笔记

1软件需求分析是保证软件质量的重要步骤&#xff0c;它的实施应该是在 软件定义阶段 1语句覆盖最弱&#xff0c;只需要让程序中的语句都执行一遍即可 。分支覆盖又称判定覆盖&#xff1a;使得程序中每个判断的取真分支和取假分支至少经历一次&#xff0c;即判断的真假均曾被满足…

K8S命令行可视化实验

以下为K8s命令行可视化工具的实验内容&#xff0c;相比于直接使用命令行&#xff0c;可视化工具可能更直观、更易于操作。 Lens Lens是用于监控和调试的K8S IDE。可以在Windows、Linux以及Mac桌面上完美运行。在 Kubernetes 上&#xff1a; 托管地址&#xff1a;github/lensa…

登录者个人信息查询

目录 &#x1f95e;1.vo层描述 &#x1f37f;2..vo层创建 &#x1f32d;3.编写controller层 &#x1f953;4.service层 &#x1f9c2;5.测试 1.vo层描述 Spring Boot项目中的实体类通常用于映射数据库表&#xff0c;包含了业务对象的所有属性。然而&#xff0c;前端或其…

Verilog基础【一】

文章目录 1.1 第一个verilog设计1.2 Verilog 简介1.3 Verilog环境搭建1.4 Verilog 设计方法设计方法设计流程 2.1 Verilog 基础语法格式注释标识符与关键字 2.2 Verilog 数值表示数值种类整数数值表示方法实数表示方法十进制&#xff1a;科学计数法&#xff1a; 字符串表示方法…

如何做慢查询优化?

如何做慢查询优化&#xff1f; 这个问题可以说是一个高频问题&#xff0c;总是被问到&#xff0c;今天来总结下这个问题。 慢查询&#xff0c;就是 SQL 查询中耗时比较大的一类查询&#xff0c;MySQL 提供了慢查询日志 slow_query_log&#xff0c; 它会记录耗时大于我们设置…

【Chapter2】进程、线程与作业,计算机操作系统教程,第四版,左万利,王英

文章目录 [toc] 一、多道程序设计1.1单道程序设计的缺点1.2多道程序设计的提出1.3多道程序设计存在的问题 二、进程的引入2.1进程的概念2.2进程的组成2.2.1进程控制块2.2.2程序 2.3进程的类型及特征2.3.1进程的类型2.3.2进程的特征 2.4进程的状态及转换2.4.1进程的状态创建态就…

项目亮点—动态线程池管理工具

问题 你是否在项目中使用线程池遇到过以下问题&#xff1f; 1.创建线程池核心参数不好评估&#xff0c;随着业务流量的波动&#xff0c;极有可能出现生产故障。 2.不支持优雅关闭&#xff0c;当项目关闭时&#xff0c;大量正在运行的线程池任务被丢弃。 3.不支持运行时监控…

java每日一题——分礼物(多线程运用)

前言&#xff1a; 运用了多线程的综合案例&#xff0c;顺便熟悉一下其他语法。打好基础&#xff0c;daydayup!!! 题目&#xff1a; 有100份礼物&#xff0c;小红小明同时发送&#xff0c;当剩下的礼物小于10份的时候则不再送出&#xff0c;利用多线程模拟该过程并将线程的名称…

R2GenCMN中的Encoder_Decoder结构

R2GenCMN中的 Encoder_Decoder 结构 Encoder_Decoder 结构直接关系到文本的生成&#xff0c;它结构参考的transformer的结构 我们这里主要看代码的实现&#xff0c;从视觉编码器的输出开始 1. 模型结构 首先介绍一下整体结构&#xff0c;这里的baseCMN其实就是一个包装了的T…

2024年noc指导教师认证测评参考试题题目5-6合集

[noc指导教师认证] 测评参考试题 说明:NOC教师指导认证考试题目是从题库里抽题,因此每位老师每次考试题目都不一样以下题目为测试考试时收集到的一些题目,作为辅助提供给各位老师,老师们可以记住题目及答案的具体内容 (选项顺序会变),以免考试时遇到。2024年的做的题目有的…

两张图片相似度匹配算法学习路线

大纲&#xff1a;​​​​​​目标跟踪基础&#xff1a;两张图片相似度算法-腾讯云开发者社区-腾讯云 (tencent.com) 目标跟踪基础&#xff1a;两张图片相似度算法 (qq.com) 一、传统方法 1.欧式距离&#xff08;用于判断是否完全相同&#xff09; [三维重建] [机器学习] 图…