Spring面试

news2025/7/18 8:19:31

1. IOC

(1)如何实现一个IOC容器

(2)IOC理解

(3)BeanFactory

BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身;ApplicationContext 面向使用 Spring 框架的开发者,几乎所有的应用场合我们都直接使用 ApplicationContext 而非底层的BeanFactory。

(4)ApplicationContext

ApplicationContext 由 BeanFactory 派 生 而 来 , 提 供 了 更 多 面 向 实 际 应 用 的 功 能 。

(5)BeanFactory 和 ApplicationContext有什么区别?

BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做 Spring的容器。

0)def:

BeanFactory: 简单粗暴,可以理解为就是个 HashMap,Key 是 BeanName,Value 是 Bean 实例。通常只提供注册(put),获取(get)这两个功能。我们可以称之为 低级容器

ApplicationContext: 可以称之为高级容器。因为他比 BeanFactory 多了更多的功能。他继承了多个接口。因此具备了更多的功能。所以你看他的名字,已经不是 BeanFactory 之类的工厂了,而
是 “应用上下文”, 代表着整个大容器的所有功能。该接口定义了一个 refresh 方法,此方法是所有阅读Spring 源码的人的最熟悉的方法,用于刷新整个容器,即重新加载/刷新所有的 bean。
 

1)实现原理:

BeanFactory:

1.1)加载配置文件,解析成 BeanDefinition 放在 Map 里。
1.2)调用 getBean 的时候,从 BeanDefinition 所属的 Map 里,拿出
Class 对象进行实例化,同时,如果有依赖关系,将递归调用 getBean 方法 —— 完成依赖注入

ApplicationContext:
包含了低级容器的功能,当他执行 refresh 模板方法的时候,将刷新整个容器的 Bean。同时其作为高级容器,包含了太多的功能。一句话,他不仅仅是 IoC。他支持不同信息源头,支持BeanFactory 工具类,支持层级容器,支持访问文件资源,支持事件发布通知,支持接口回调等等。


2)依赖关系:
BeanFactory:是Spring里面最底层的接口,包含了各种Bean的定义,读取 bean配置文档,管理bean的加载、实例化,控制bean的生命周期,维护bean 之间的依赖关系。
ApplicationContext接口:是BeanFactory的子接口,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能。

3)加载方式
BeanFactroy:采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean 时(调用getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常。
ApplicationContext:它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。 ApplicationContext启动后预载入所有的单实例Bean,通过预载入单实例bean ,确保当你需要的时候,你就不用等待,因为它们已经创建好了。相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。

4)创建方式
BeanFactory:通常以编程方式被创建。

ApplicationContext:能以编程方式和声明方式创建,如使用ContextLoader。

5)注册方式

BeanFactory和ApplicationContext都支持BeanPostProcessor,BeanFactoryPostProcessor的使用

BeanFactory:手动注册
ApplicationContext:自动注册

6)BeanFactory和ApplicationContext的关系

(6)BeanFactory和FactoryBean

BeanFactory:Bean工厂,是一个工厂(Factory),我们Spring IoC容器的最顶层接口就是这个
BeanFactory,它的作用是管理Bean,即实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
FactoryBean:工厂Bean,是一个Bean,作用是产生其他bean实例。通常情况下,这种bean没有什么特别的要求,仅需要提供一个工厂方法,该方法用来返回其他bean实例。通常情况下,bean无须自己实现工厂模式,Spring容器担任工厂角色;但少数情况下,容器中的bean本身就是工厂,其作用是产生其它bean实例。
(7)ApplicationContext通常的实现是什么?

FileSystemXmlApplicationContext :此容器从一个XML文件中加载beans 的定义,XML Bean 配置文件的全路径名必须提供给它的构造函数。
ClassPathXmlApplicationContext:此容器也从一个XML文件中加载beans 的定义,这里,你需要正确设置classpath因为这个容器将在classpath里找 bean配置。
WebXmlApplicationContext:此容器加载一个XML文件,此文件定义了一个WEB应用的所有bean。

()什么是bean的自动装配
()什么是Spring的依赖注入?

 

控制反转IoC是一个很大的概念,可以用不同的方式来实现。其主要实现方式有两种:依赖注入和依赖查找依赖注入:相对于IoC而言,依赖注入(DI)更加准确地描述了IoC的设计理念。所谓依赖注入(Dependency Injection),即组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。
()依赖注入的基本原则

依赖注入的基本原则是:应用组件不应该负责查找资源或者其他依赖的协作对象。配置对象的工作应该由IoC容器负责,“查找资源”的逻辑应该从应用组件的代码中抽取出来,交给IoC容器负责。容器全权负责组件的装配,它会把符合依赖关系的对象通过属性(JavaBean中的setter)或者是构造器传递给需要的对象。
()依赖注入有什么优势

查找定位操作与应用代码完全无关。
不依赖于容器的API,可以很容易地在任何容器以外使用应用对象。
不需要特殊的接口,绝大多数对象可以做到完全不必依赖容器。

()如何创建一个如何给Spring 容器提供配置元数据?Spring有几种配置方式
1)XML配置文件
2)基于注解的配置
3)基于java的配置

 

(7)Spring 依赖注入几种方式

0)接口注入(Interface Injection):作废

1)构造器注入(Constructor Injection):构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖。

2)setter方法注入(Setter Injection):Setter方法注入是容器通过调用无参构造器或无参static工厂 方法实例化bean之后,调用该bean的setter方法,即实现了基于setter的依赖注入。

()Spring基于xml注入bean的几种方式

1) Set方法注入;
2) 构造器注入:①通过index设置参数的位置;②通过type设置参数类型;
3)静态工厂注入;
4) 实例工厂;
 

(8)5 种不同方式的自动装配

()Spring框架中的单例bean是线程安全的吗?

不是,Spring框架中的单例bean不是线程安全的
spring 中的 bean 默认是单例模式,spring 框架并没有对单例 bean 进行多线程的封装处理。
实际上大部分时候 spring bean 无状态的(比如 dao 类),所有某种程度上来说 bean 也是安全的,但如果 bean 有状态的话(比如 view model 对象),那就要开发者自己去保证线程安全了,最简单的就是改变 bean 的作用域,把“singleton”变更为“prototype”,这样请求 bean 相当于 new Bean() 了,所以就可以保证线程安全了。
有状态就是有数据存储功能。
无状态就是不会保存数据。

()Spring如何处理线程并发问题?
在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域,因为Spring对一些Bean中非线程安全状态采用ThreadLocal进行处理,解决线程安全问题。
ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。同步机制采用了“时间换空间”的方式,仅提供一份变量,不同的线程在访问前需要获取锁,没获得锁的线程则需要排队。而ThreadLocal采用了“空间换时间”的方式。
ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。

()哪些是重要的bean生命周期方法? 你能重载它们吗?

有两个重要的bean 生命周期方法,第一个是setup , 它是在容器加载bean的时候被调用。第二个方法是 teardown 它是在容器卸载类的时候被调用。bean 标签有两个重要的属性(init-method和destroy-method)。用它们你可以自己定制初始化和注销方法。它们也有相应的注解(@PostConstruct和@PreDestroy)。

()什么是Spring的内部bean?什么是Spring inner beans?

在Spring框架中,当一个bean仅被用作另一个bean的属性时,它能被声明为一个内部bean。内部bean可以用setter注入“属性”和构造方法注入“构造参数”的方式来实现,内部bean通常是匿名的,它们的Scope一般是prototype。

()在 Spring中如何注入一个java集合?
Spring提供以下几种集合的配置元素:类型用于注入一列值,允许有相同的值。
类型用于注入一组值,不允许有相同的值。
类型用于注入一组键值对,键和值都只能为String类型。
()什么是bean装配?
装配,或bean 装配是指在Spring 容器中把bean组装到一起,前提是容器需要知道bean的依赖关系,如何通过依赖注入来把它们装配到一起。

()什么是bean的自动装配?
在Spring框架中,在配置文件中设定bean的依赖关系是一个很好的机制,Spring 容器能够自动装配相互合作的bean,这意味着容器不需要和配置,能通过Bean工厂自动处理bean之间的协作。这意味着 Spring可以通过向Bean Factory中注入的方式自动搞定bean之间的依赖关系。自动装配可以设置在每个bean上,也可以设定在特定的bean上。

()使用@Autowired注解自动装配的过程是怎样的?
使用@Autowired注解来自动装配指定的bean。在使用@Autowired注解之前需要在Spring配置文件进行配置。
在启动spring IoC时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器,当容器扫描到@Autowied、@Resource或@Inject时,就会在IoC容器自动查找需要的 bean,并装配给该对象的属性。在使用@Autowired时,首先在容器中查询对应类型的bean:
如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据;
如果查询的结果不止一个,那么@Autowired会根据名称来查找;
如果上述查找的结果为空,那么会抛出异常。解决方法时,使用required=false。

()自动装配有哪些局限性?

自动装配的局限性是:重写:你仍需用 和 配置来定义依赖,意味着总要重写自动装配。
基本数据类型:你不能自动装配简单的属性,如基本数据类型,String字符串,和类。
模糊特性:自动装配不如显式装配精确,如果有可能,建议使用显式装配。
 

2. AOP

(1)AOP理解

(2)AOP 核心概念

1)切面(aspect):类是对物体特征的抽象,切面就是对横切关注点的抽象
2)横切关注点:对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点。
3)连接点(joinpoint):被拦截到的点,因为 Spring 只支持方法类型的连接点,所以在 Spring 中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器。
4)切入点(pointcut):对连接点进行拦截的定义
5)通知(advice):所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类。
6)目标对象:代理的目标对象
7)织入(weave):将切面应用到目标对象并导致代理对象创建的过程 8、引(introduction):在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段。

(3)AOP 主要应用场景

()如何理解 Spring 中的代理?

将 Advice 应用于目标对象后创建的对象称为代理。在客户端对象的情况下,目标对象和代理对象是相同的。

Advice + Target Object = Proxy

 ()Spring AOP and AspectJ AOP 有什么区别?AOP 有哪些实现方式?
AOP实现的关键在于代理模式,AOP代理主要分为静态代理和动态代理。静态代理的代表为AspectJ;动态代理则以Spring AOP为代表。静态代理与动态代理区别在于生成AOP代理对象的时机不同,相对来说AspectJ 的静态代理方式具有更好的性能,但是AspectJ需要特定的编译器进行处理,而Spring AOP则无需特定的编译器处理。

1) AspectJ静态代理的增强,所谓静态代理,就是AOP框架会在编译阶段生成AOP代理类,因此也称为编译时增强,他会在编译阶段将AspectJ(切面)织入到Java字节码中,运行的时候就是增强之后的AOP对象。

2) Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法
 

(4)AOP 两种动态代理方式

Spring 提供了两种方式来生成代理对象: JDKProxy 和 Cglib,具体使用哪种方式生成由
AopProxyFactory 根据 AdvisedSupport 对象的配置来决定。默认的策略是如果目标类是接口,则使用JDK 动态代理技术,否则使用 Cglib 来生成代理。
1)JDK 动态代理
JDK 动态代理主要涉及到 java.lang.reflect 包中:InvocationHandler接口和Proxy类
InvocationHandler 通过invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织
在一起
;接着,Proxy利用 InvocationHandler动态创建一个符合某一接口的的实例, 生成目标类的
代理对象。
2)CGLib 动态代理
如果代理类没有实现 InvocationHandler 接口,那么Spring AOP会选择使用CGLIB来动态代理目标
类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成指定
类的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现AOP
。CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的

@Aspect public class TransactionDemo {
	@Pointcut(value="execution(* com.yangxin.core.service.*.*.*(..))")
	public void point(){
	}
	@Before(value="point()") 
	public void before(){
	System.out.println("transaction begin");
	}
	@AfterReturning(value = "point()") 
	public void after(){
	System.out.println("transaction commit");
	}
	@Around("point()")
	public void around(ProceedingJoinPoint joinPoint) throws Throwable{
	System.out.println("transaction begin"); joinPoint.proceed();
	System.out.println("transaction commit");
	}
}

3)区别

在功能上讲,实际上Cglib代理并不如JDK代理(如果大家都按接口-实现的方式来设计类)。但是从效率上将,Cglib远胜JDK代理。其实从原理也能理解,直接通过类的方法调用,肯定要比通过反射调用的时间更短。
 

(5)纵观 AOP 编程,其中需要程序员参与的只有 3 个部分:
1)定义普通业务组件。
2)定义切入点,一个切入点可能横切多个业务组件。
3)定义增强处理,增强处理就是在 AOP 框架为普通业务组件织入的处理动作。

(6)AOP 代理的方法大致有如下公式:
代理对象的方法 = 增强处理 + 被代理对象的方法
 

()连接点的支持,而且它不支持构造器连接点。方法之外的连接点拦截功能,我们在Spring AOP 中,关注点和横切关注的区别是什么?在spring aop 中 concern 和 cross-cutting concern 的不同之处

关注点(concern)是应用中一个模块的行为,一个关注点可能会被定义成一个我们想实现的一个功能。
横切关注点(cross-cutting concern)是一个关注点,此关注点是整个应用都会使用的功能,并影响整个应用,比如日志,安全和数据传输,几乎应用的每个模块都需要的功能。因此这些都属于横切关注点。

()什么是切面 Aspect?

aspect 由 切点pointcount 和 通知advice 组成。 它既包含了横切逻辑的定义, 也包括了连接点的定义. Spring AOP 就是负责实施切面的框架, 它将切面所定义的横切逻辑编织到切面所指定的连接点中。
AOP 的工作重心在于如何将增强编织目标对象的连接点上, 这里包含两个工作:
1)如何通过 pointcut 和 advice 定位到特定的 joinpoint 上。
2)如何在 advice 中编写切面代码。
可以简单地认为, 使用 @Aspect 注解的类就是切面

()有几种不同类型的自动代理?
BeanNameAutoProxyCreator
DefaultAdvisorAutoProxyCreator
Metadata autoproxying
 

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

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

相关文章

Zookeeper和Eureka的区别

Zookeeper: CP设计(强⼀致性),⽬标是⼀个分布式的协调系统,⽤于进⾏资源的统⼀管理。当节点crash后,需要进⾏leader的选举,在这个期间内,zk服务是不可⽤的。 eureka: AP设计(高可用&…

动态规划--(不同的子序列,编辑距离,两个字符串的删除)

代码随想录day56 动态规划模块 不同的子序列,编辑距离,两个字符串的删除 文章目录1.leetcode 115. 不同的子序列1.1思路及详细步骤1.2 代码示例2.leetcode 583. 两个字符串的删除操作2.1思路及详细步骤2.2 代码示例3.leetcode 72. 编辑距离3.1思路及详细步骤3.2 代码…

绝对最直白的MySQL MVCC机制总结,免费拿走

🍁 作者:知识浅谈,CSDN签约讲师,后端领域优质创作者,阿里云社区技术博主,热爱分享创作 💒 公众号:知识浅谈 📌 擅长领域:全栈工程师、爬虫、ACM算法 绝对最直…

项目实战 - tpshop商城项目环境搭建

一、环境部署准备 1、软件工具准备 1.1、Vmware虚拟机 1. 在本机上安装好Vmware虚拟机 2. 在虚拟机上安装并运行Linux系统 3. 注意: 实际工具中使用云服务器 1.2、远程连接工具 1. 在本机上安装好远程连接工具 (xshell / putty / FinalShell(推荐)) …

三种常见的特征选择方法

特征选择 特征选择是特征工程里的一个重要问题,其目标是寻找最优特征子集。特征选择能剔除不相关(irrelevant)或冗余(redundant )的特征,从而达到减少特征个数,提高模型精确度,减少运行时间的目的。并且常能听到“数据和特征决定…

k8s master 实现高可用

Kubernetes高可用master架构 k8s的高可用,主要是实现Master节点的高可用。那么我们看看各个组件是如何解决高可用的。 Kubelet、Kube-proxy:只工作在当前Node节点上,无需高可用。 etcd:etcd如果是放在集群内部的,在…

长文讲解Linux内核性能优化的思路和步骤

一.性能调优简介 1.为什么要进行性能调优? 1) 编写的新应用上线前在性能上无法满足需求,这个时候需要对系统进行性能调优 2) 应用系统在线上运行后随着系统数据量的不断增长、访问量的不断上升,系统的响应速度通常越…

js-学习链表

链表基础概念 链表和数组一样,可以用于存储一系列连续的元素。链表中的元素在内存中不必是连续的空间。链表的每一个元素有一个由一个存储元素本身的节点和一个指向下一个元素的引用组成(指针和连接)。 链表构成 数据指针 链表优点 1.内存空间不是必须连续的&a…

实践分享:30分钟在电脑端运行小程序

预计实现效果:在电脑桌面端实现小程序运行 技术实现:小程序容器技术实现(案例使用FinClip SDK) 技术的原理: 该 SDK 主要包括应用交互层、安全防护、网络通信控制和安全运行容器四个组件。 应用交互层:应用交互层是…

DBSCAN算法实现【超详细注释】

DBSCAN 算法步骤 设置每个对象为未访问 随机选择一个未访问的点ppp,标记ppp表示访问 如果p的半径为nnn的邻域中至少存在MinPts个对象 我们就创建一个新的簇,并将ppp加入ccc设N 是ppp邻域中对象的集合对在NNN中的每个点p′pp′ 如果p′pp′是未访问的 标记p′pp′…

Matlab:数值积分与符号计算

Matlab数值积分定积分的数值求解实现自适应积分算法梯形积分法累计梯形积分多重定积分的数值求解实现符号计算符号对象及其运算符号微积分符号极限符号导数求不定积分符号方程求解数值积分 数值积分,用于求定积分的近似值。在数值分析中,数值积分是计算定…

SQL Server简介

SQL Server是微软的一款关系型数据库。某些平台吹得天花烂坠,今天第一次在自己的项目中使用了下,感觉不是那么好,特别是SQL语句的支持度还是很欠缺,如limit等都不支持,还有特别单双引号都是需要特别注意的,下面是SQL S…

从0到1CTFer成长之路——1git(全网最详细)

1.1.2.1 git 泄露 (1) 常规git泄露 安装docker sudo apt-get update sudo apt-get install docker 安装容器 docker pull ubuntu:18.04 然后发现请求超时 我们需要阿里云的镜像加速器 我们按照要求配置文件 没有/etc/docker 就自己创建 sudo mkdir -p /etc/docker 然后写入…

Cookie与Session 以及给CBV添加装饰器

文章目录Cookie与Session1、Django操作cookie简单实现用户登录加入装饰器2、Django操作session设置session获取session过期时间清除sessionCBV添加装饰器Cookie与Session HTTP被设计为”⽆态”,也就是俗称“脸盲”。 这⼀次请求和下⼀次请求 之间没有任何状态保持&…

跨模态神经搜索实践VCED 环境准备

跨模态神经搜索实践 环境准备 本文基于WSL2及docker进行环境搭建 1. 安装和配置WSL2 Ubuntu发行版 1.1 安装WSL2 Ubuntu 相关安装命令: wsl --install:默认安装Ubuntu发行版wsl --list --online:查看可支持的发行版本wsl --install -d &…

如何将 wordfile 添加到 UltraEdit 或 UEStudio

UltraEdit 本身支持开箱即用的最常用编程和标记语言的语法突出显示。我们也有数百个其他语言的 wordfile,但是,很容易找到和添加您需要的语言! 重要提示:此电源提示适用于运行 UltraEdit v15.00或 UEStudio v09.10及更高版本的用户…

Ubuntu18.04系统安装nginx

Ubuntu18.04系统安装nginx一、在线安装 Nginx二、离线安装 Nginx参考链接请确保以具有 sudo 权限的用户身份登录,并且您没有在端口 80 或 443 上运行 Apache 或任何其他 Web 服务器。 一、在线安装 Nginx 简介:Nginx (engine x) 是一个免费的&#xff0…

swift-类属性

了解属性之前,需要先了解前面的swift-类结构内容 - swift-类结构源码探寻 FieldDescriptor TargetClassDescriptor {var Flags: ContextDescriptorFlags // uint32var Parent: TargetRelativeContextPointer // Int32var Name: TargetRelativeDirectPointer // I…

Markdown还能这么玩?这款开源神器绝了!

Markdown是一款轻量级标记语言,由于它易读易写的特性,很多程序员用它来写项目文档。其实Markdown的功能不止于此,结合一些工具使用还可以用来做PPT,今天带大家使用Markdown来做一个PPT,看看到底有多炫酷! S…

《springboot那些事》

注&#xff1a;static目录、主要用于存放非模板引擎渲染的资源。 ​ template目录&#xff0c;存放渲染引擎页面的资源。 一句话&#xff1a;用模板引擎的话&#xff0c;就放template目录、否则static目录。 一、使用thymeleaf 引入thymealeaf坐标 <dependency><…