2024年java面试(三)--spring篇

news2024/11/26 0:54:41

文章目录

  • 1.spring的bean是线程安全的吗?
  • 2.什么是Spring IOC 容器?
  • 3.DI 依赖注入
  • 4.如何实现一个IOC容器
  • 5.Spring 的 IoC支持哪些功能?
  • 6.IOC初始化过程
  • 7.面向切面编程(AOP)
  • 8.AOP 思想
  • 9.AOP的应用场景
  • 10.AOP通知类型
  • 11.Spring AOP编程两种方式
  • 12.使用注解@Aspect流程
  • 13.AOP的相关术语
  • 14.AOP编程底层实现机制


1.spring的bean是线程安全的吗?

spring的默认bean作用域是单例的,单例的bean不是线程安全的,但是开发中大部分的bean都是无状态的,不具备存储功能,比如controller、service、dao,他们不需要保证线程安全。
如果要保证线程安全,可以将bean的作用域改为prototype,比如像Model View。
另外还可以采用ThreadLocal来解决线程安全问题。ThreadLocal为每个线程保存一个副本变量,每个线程只操作自己的副本变量。


2.什么是Spring IOC 容器?

IoC(Inverse of Control:控制反转)是⼀种设计思想,就是将原本在程序中⼿动创建对象的控制权,交由Spring框架来管理。 IoC 在其他语⾔中也有应⽤,并⾮ Spring 特有。
IoC 容器是 Spring⽤来实现 IoC 的载体,将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注⼊。这样可以很⼤程度上简化应⽤的开发,把应⽤从复杂的依赖关系中解放出来。 IoC 容器就像是⼀个⼯⼚⼀样,当我们需要创建⼀个对象的时候,只需要配置好配置⽂件/注解即可,完全不⽤考虑对象是如何被创建出来的。


3.DI 依赖注入

DI:(Dependancy Injection:依赖注入)站在容器的角度,将对象创建依赖的其他对象注入到对象中。


4.如何实现一个IOC容器

① 配置文件配置包扫描路径
② 递归包扫描获取.class文件
③ 反射、确定需要交给IOC管理的类
④ 对需要注入的类进行依赖注入

  • 配置文件中指定需要扫描的包路径
  • 定义一些注解,分别表示访问控制层、业务服务层、数据持久层、依赖注入注解、获取配置文件注解
  • 从配置文件中获取需要扫描的包路径,获取到当前路径下的文件信息及文件夹信息,我们将当前路径下所有以.class结尾的文件添加到一个Set集合中进行存储
  • 遍历这个set集合,获取在类上有指定注解的类,并将其交给IOC容器,定义一个安全的Map用来存储这些对象
  • 遍历这个IOC容器,获取到每一个类的实例,判断里面是有有依赖其他的类的实例,然后进行递归注入。

5.Spring 的 IoC支持哪些功能?

Spring 的 IoC 设计支持以下功能:

①依赖注入
②依赖检查
③自动装配
④支持集合
⑤指定初始化方法和销毁方法
⑥支持回调某些方法(但是需要实现 Spring 接口,略有侵入)

其中,最重要的就是依赖注入,从 XML 的配置上说,即 ref 标签。对应 Spring RuntimeBeanReference 对象。

对于 IoC 来说,最重要的就是容器。容器管理着 Bean 的生命周期,控制着 Bean 的依赖注入。


6.IOC初始化过程

IOC容器初始化是由refresh()方法来启动的,这个方法标志着IOC容器的正式启动。Spring将IOC容器启动的过程分开,并使用不同的模块来完成,如使用ResourceLoader,BeanDefinition等模块, IOC容器的启动主要包括三个过程:

Resource定位过程: Resource定位指beanDefinition的资源定位,由ResourceLoader通过统一的Resource接口来完成,这个Resource对各种形式的BeanDefinition的使用都提供了统一的接口。这个过程类似于容器寻找数据的过程。

BeanDefinition的载入: BeanDefinition载入过程指的是把用户定义好的Bean表示为容器内部的数据结构,这个容器的数据结构其实就是BeanDefinition。实际上BeanDefinition就是POJO对象在容器的抽象,通过BeanDefinition来定义的数据结构,像是世间万物在java中的抽象,java的对象又在容器中的抽象就是BeanDefinition。

向容器注册BeanDefinition: 这个注册过程是通过调用BeanDefinitionRegistry接口来完成的,就是把载入过程中解析得到的BeanDefinition向IOC容器进行注册。通过下面的源码可以得到,注册过程就是在IOC容器将BeanDefinition注入到一个HashMap中,IOC容器就是通过这个HashMap来持有BeanDefinition数据的。


7.面向切面编程(AOP)

在这里插入图片描述
AOP (Aspect Oriented Programing) 称为:面向切面编程,它是一种编程思想。

AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码的编写方式(例如性能监视、事务管理、安全检查、缓存、日志记录等)。

Spring AOP就是基于动态代理的,如果要代理的对象,实现了某个接⼝,那么Spring AOP会使⽤JDKProxy,去创建代理对象,⽽对于没有实现接⼝的对象,就⽆法使⽤ JDK Proxy 去进⾏代理了,这时候Spring AOP会使⽤基于asm框架字节流的Cglib动态代理 ,这时候Spring AOP会使⽤ Cglib ⽣成⼀个被代理对象的⼦类来作为代理。


8.AOP 思想

基于代理思想,对原来目标对象,创建代理对象,在不修改原对象代码情况下,通过代理对象,调用增强功能的代码,从而对原有业务方法进行增强 ! 切面:需要代理一些方法和增强代码 。


9.AOP的应用场景

场景一: 记录日志

场景二: 监控方法运行时间 (监控性能)

场景三: 权限控制(通过Around,可以在执行方法前进行权限验证)

场景四: 缓存优化 (第一次调用查询数据库,将查询结果放入内存对象, 第二次调用, 直接从内存对象返回,不需要查询数据库 )

场景五: 事务管理 (调用方法前开启事务, 调用方法后提交或者回滚、关闭事务 )


10.AOP通知类型

前置通知 Before advice:在连接点前面执行,前置通知不会影响连接点的执行,除非此处抛出异常

后置通知 After returning advice:在连接点正常执行完成后执行,如果连接点抛出异常,则不会执行

异常通知 After throwing advice:在连接点抛出异常后执行

最终通知 After (finally) advice:在连接点执行完成后执行,不管是正常执行完成,还是抛出异常,都会执行返回通知中的内容

环绕通知 Around advice:环绕通知围绕在连接点前后,能在方法调用前后自定义一些操作,还需要负责决定是继续处理 join point (调用 ProceedingJoinPoint 的 proceed 方法)还是中断执行


11.Spring AOP编程两种方式

①Spring AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类植入增强代码。

②AsPectJ是一个基于Java语言的AOP框架,Spring2.0开始,Spring AOP引入对Aspect的支持。


12.使用注解@Aspect流程

1.切面类 @Aspect: 定义切面类,加上@Aspect、@Component注解

2.切点 @Pointcut

3.Advice通知,在切入点上执行的增强处理,主要有五个注解

4.JoinPoint :方法中的参数JoinPoint为连接点对象,它可以获取当前切入的方法的参数、代理类等信息,因此可以记录一些信息,验证一些信息等;

@Aspect
@Component
//设置注解执行的顺序
@Order(1)
public class AspectTest {
 
    /**
     * 定义切点,切点为对应controller
     */
    @Pointcut("execution(public * com.example.zcs.Aop.controller.*.*(..))")
    public void aopPointCut(){
 
    }
 
    @Before("aopPointCut()")
    public void testbefor(JoinPoint joinPoint) {
        illegalParam(joinPoint);
        System.out.println("执行方法之前执行。。。。。");
    }
    
 
    @After("aopPointCut()")
    public void testAfter(JoinPoint joinPoint) {
        //illegalParam(joinPoint);
        System.out.println("执行方法之后执行。。。。。");
    }
 
    /**
     *获取请求参数
     * @param joinPoint
     * @return
     */
    private static void  illegalParam(JoinPoint joinPoint) {
        if(joinPoint == null){
            return;
        }
        boolean flag = false;
        try{
            // 参数值
            Object[] args = joinPoint.getArgs();
            if (args != null) {
                for (Object o : args) {
                    System.out.println(o);
 
                }
            }
        }catch(Exception e){
        }
    }
    
}


13.AOP的相关术语

Aspect(切面) : 是通知和切入点的结合,通知和切入点共同定义了关于切面的全部内容—它的功能、在何时和何地完成其功能

joinpoint(连接点) :所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点.

Pointcut(切入点) :所谓切入点是指我们要对哪些joinpoint进行拦截的定义.
通知定义了切面的”什么”和”何时”,切入点就定义了”何地”.

Advice(通知) :所谓通知是指拦截到joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)

Target(目标对象) :代理的目标对象

weaving(织入) :是指把切面应用到目标对象来创建新的代理对象的过程.切面在指定的连接点织入到目标对象

Introduction(引介) :在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field.


14.AOP编程底层实现机制

AOP 就是要对目标进行代理对象的创建, Spring AOP是基于动态代理的,基于两种动态代理机制: JDK动态代理和CGLIB动态代理

JDK动态代理
JDK动态代理,针对目标对象的接口进行代理 ,动态生成接口的实现类 !(必须有接口)
JDK动态代理的缺点: 只能面向接口代理,不能直接对目标类进行代理 ,如果没有接口,则不能使用JDK代理。
Cglib动态代理
Cglib动态代理基于父类,Cglib的引入为了解决类的直接代理问题(生成代理子类),不需要接口也可以代理 !
什么是cglib ? CGLIB(Code Generation Library)是一个开源项目!是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。

静态代理
静态代理相当于是多写了一个代理类,在调用的时候调用的是代理类,在代理类中的处理还是原生的处理逻辑,不过在前后添加上需要添加的代码。 缺点:需要为每一个被代理的对象都创建一个代理类。
特点
代理角色和真实角色都需要实现同一个接口,
真实角色专注于自己的事情,
代理角色目的就是帮助真实角色完成一件事情
多线程的实现方式2:实现一个接口Runnable 使用的就是"静态代理"的思想

代理知识小结
区别
①Jdk代理:基于接口的代理,一定是基于接口,会生成目标对象的接口类型的子对象。
②Cglib代理:基于类的代理,不需要基于接口,会生成目标对象类型的子对象。
③Spring AOP 优先对接口进行代理 (使用Jdk动态代理)
④如果目标对象没有实现任何接口,才会对类进行代理 (使用cglib动态代理)

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

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

相关文章

linuxdeploy安装CentOS7搭建django服务

目录 一、busybox安装 二、linuxdeploy安装 三、linuxdeploy软件设置及安装 四、CentOS基础环境配置 五、CentOS7 上安装Python3.8.10 六、systemctl的替代品 七、CentOS7 上安装mysql5.2.27数据库 八、CentOS7 上安装Nginx服务 九、Django项目应用部署 参考文献: 一…

【100天精通python】Day46:python网络编程基础与入门

目录 专栏导读 1 网络编程的基础 2. 基本概念和协议 2.1 计算机网络基础 2.2 网络协议、IP地址、端口号 2.3 常见网络协议 3. 套接字编程 3.1 套接字的基本概念 3.2 套接字的基本操作 3.3 套接字通信模型和方法:send、recv 3.3.1 TCP通信模型 3.3.2 U…

模拟实现库函数strcpy以及strlen

目录 strcpy 介绍库函数strcpy 例子 分析模拟实现思路 补充 assert宏 const关键字来修饰源字符串的指针 代码展示 strlen 介绍库函数strcpy 例子 分析模拟实现思路 计数器 递归 指针-指针 代码展示 计数器 递归 指针-指针 strcpy 介绍库函数strcpy 这个库函…

docker 04.更加重要的命令

之前的都是基础命令, 前台交互进程和后台守护进程: 重新进入容器: docker中的导入导出: docker中的拷贝到:

SpringBoot整合OpenAI实现AI聊天 (精简demo)

1. OpenAI官网/*** 官网获取密钥基本条件* * 1. 翻墙, 能访问外网* 2. 拥有国外手机号码* 3. 注册账号* 4. 获取密钥*/https://openai.com/ 2. 获取OpenAI密钥 (怎么简单怎么来) // 直接在淘宝上购买, 买多几个随机访问 sk-xxxx 3. 依赖 <dependency><groupId>c…

智能客服系统:解决企业服务、管理难题的新选择

在数字化时代&#xff0c;智能客服系统是企业服务、管理的新选择。智能客服系统可以通过自然语言处理、人工智能等技术实现与顾客的智能对话&#xff0c;提升企业客服效率和服务质量。同时&#xff0c;智能客服系统也可以为企业提供实时数据分析和监管&#xff0c;进一步优化管…

图解算法--查找算法

目录 查找算法 一、顺序查找 二、二分法查找 三、插值查找法 四、斐波那契查找法 查找算法 查找算法根据数据量的大小&#xff0c;可以将其分为以下两种 内部查找&#xff1a;内部查找是指在内存或内部存储器中进行查找操作的算法。内部查找适用于数据量较小、存储在内存…

实时记录开房信息,在线开房记录查询工具

随着社会的高速发展&#xff0c;异地出差人士越来越多&#xff0c;往往全国跑&#xff0c;每每去到一个地区都要开房休息&#xff0c;当开房数量越来越多的时候&#xff0c;往往会把数据混乱&#xff0c;不利于回公司后的出差费用报销&#xff0c;故此发现了一款实时记录实时查…

h3c多系列路由器存在任意用户登录漏洞

该文章来自作者日常学习笔记&#xff0c;也有部分文章是经过作者授权和其他公众号白名单转载&#xff0c;未经授权&#xff0c;严禁转载&#xff0c;如需转载&#xff0c;联系开白。请勿利用文章内的相关技术从事非法测试&#xff0c;如因此产生的一切不良后果与文章作者无关。…

好用的c++11纳米级的测量时间消耗的类

需要包含的头文件及类实现&#xff1a; #include <chrono> #include <thread>class Timer { public:Timer() : m_StartTimepoint(std::chrono::high_resolution_clock::now()) {}~Timer() {Stop();}void Stop() {auto endTimepoint std::chrono::high_resolution…

利用改进的遗传算法(种群隔离与个体迁移)mpi并行解决tsp问题

序 关于tsp问题的概述以及如何使用遗传算法进行求解已经在上一篇文章中说明了&#xff1a;遗传算法解决TSP问题. 但是&#xff0c;作为一种演化算法&#xff0c;遗传算法还存在着许多问题&#xff0c;比如早熟的情况&#xff0c;很容易在算法前期就已经收敛了&#xff0c;大量…

得帆信息CEO张桐接受21世纪财经深度专访,表示AIGC+低代码将带来生产效率的变革

近日&#xff0c;得帆信息创始人兼CEO张桐接受了21世纪财经深度专访&#xff0c;他表示AIGC低代码的黄金组合&#xff0c;将带来生产效率的变革。 眼下&#xff0c;低代码与AI创新的联接才刚刚开始&#xff0c;也必然会带来生产效率的变革。 在AIGC汹涌的浪潮下&#xff0c;聊…

【LNMT与动静分离】

目录 一、LNMT 1.部署tomcat 1.1 单机部署 1.2 多机部署 2.部署nginx 3.部署Mariadb 4.配置Nginx 二、Nginx高级配置 1.location 2.1 应用场景 2.2 书写位置 2.3 重写条目写法 2.4 返回状态码 2.5 案例 三、动静分离 1.修改nginx配置文件 2.测试 一、LNMT 1.…

四层负载均衡的NAT模型与DR模型推导 | 京东物流技术团队

导读 本文首先讲述四层负载均衡技术的特点&#xff0c;然后通过提问的方式推导出四层负载均衡器的NAT模型和DR模型的工作原理。通过本文可以了解到四层负载均衡的技术特点、NAT模型和DR模型的工作原理、以及NAT模型和DR模型的优缺点。读者可以重点关注NAT模型到DR模型演进的原…

linux字符串处理

目录 1 C 截取字符串,截取两个子串中间的字符串2 获取该字符串后面的字符串用 strstr() 函数查找需要提取的特定字符串&#xff0c;然后通过指针运算获取该字符串后面的字符串用 strtok() 函数分割字符串&#xff0c;找到需要提取的特定字符串后&#xff0c;调用 strtok() 传入…

c语言六子棋(Alpha-Beta剪枝算法)

c语言Alpha-Beta剪枝算法六子棋介绍 Alpha-Beta剪枝算法是一种用于优化博弈树搜索的算法&#xff0c;可以在搜索过程中减少不必要的计算&#xff0c;从而提高搜索效率。该算法常用于博弈游戏&#xff0c;如六子棋。 六子棋是一种类似于五子棋的棋类游戏&#xff0c;在一个六边形…

C#: Json序列化和反序列化,集合为什么多出来一些元素?

如下面的例子&#xff0c;很容易看出问题&#xff1a; 如果类本身的无参构造函数&#xff0c; 就添加了一些元素&#xff0c;那么在序列化&#xff0c;再反序列化&#xff0c;会导致元素增加。 如果要避免&#xff0c;必须添加&#xff1a; new JsonSerializerSettings() { …

目标检测(凑字数,凑字数,为什么标题一定要五个字)

写在最前&#xff1a; 昨天七夕&#xff0c;一个人躲在家里打游戏&#xff0c;不敢出门&#xff0c;怕被喂狗粮。 一个即将步入中年的老男人&#xff0c;弱小&#xff0c;无助&#xff0c;单身&#xff0c;肥胖&#xff0c;贫穷。但是怀揣着一丢丢情怀和梦想&#xff0c;妄图吃…

运算符(个人学习笔记黑马学习)

算数运算符 加减乘除 #include <iostream> using namespace std;int main() {int a1 10;int a2 20;cout << a1 a2 << endl;cout << a1 - a2 << endl;cout << a1 * a2 << endl;cout << a1 / a2 << endl;/*double a3 …