1.Spring的三级缓存
首先要知道我们创建出一个bean要做什么事?
1.实例化------new出来
2.属性赋值------属性变量 比如 A里面有一个B,B是在这个时候放进去的
3.初始化-------一堆钩子函数,以及动态代理的生成也是在这一步
循环依赖的场景
解决思路
1.当A实例化new出来,这时候要走属性赋值,但是发现B=null
2.那么接下来就要走B的生命周期了,B 实例化new出来,要走属性赋值,
3.从某一个地方拿到A提前暴露出来的A,拿到A了之后就可以继续走B的初始化逻辑,B创建完成
4.然后再走A的生命周期,这时候走属性赋值就可以拿到B了(因为B已经创建完了),继续往下走A的初始化逻辑,A创建完成
最关键的就是,要有某一个地方,可以让A提前暴露出来,让B去引用
但是具体是怎么解决的?那就是Spring三级缓存
a.一级缓存(真正可以使用的bean)
b.二级缓存(提前暴露出来的bean)
c.三级缓存(bean工厂)
三级缓存是如何解决循环依赖的问题?具体步骤
1.最开始AB都在三级缓存中,当A在实例化new的时候,发现B没有,那就先走B的生命周期
2.当B要实例化new的时候发现A没有,那就要先创建出A,会先将A提前放到二级缓存中(提前进行A的初始化,包括A的代理对象),B拿到了A,然后B初始化完成了,B创建结束
3.再走A的生命周期,A发现三级缓存中没有自己了,那就证明自己被提前创建出来了,就去二级缓存中找,找到了之后,自己再走最后一步的A的初始化,代理对象也是在这个时候创建的,会引用A的原始原始对象,最终暴露代理对象给外部使用,A创建结束
为什么一定要有三级缓存?二级缓存不可以吗?
1.如果没有代理对象,二级缓存也是可以的
2.代码规范问题,spring不想因为解决循环依赖的问题,破坏它原本bean的生命周期流程,如果只有二级缓存,也就意味着B的生命周期走完了A的生命周期,自己的路被别人走完了,自己无路可走了
总结一下三级缓存适配的逻辑
说白了就是为了解决A依赖B,B依赖A的循环依赖的问题,而且A还有代理对象生成的逻辑
正常来说二级缓存可以解决循环依赖的问题,有三级缓存的意义在于,防止有代理对象提前生成出来了,你得有一个地方去放它(提前放入二级缓存里)
2.SpringAop
aop是什么?
面向切面编程(切面:一段代码的前后加上通用的逻辑)
那你是怎么用的?代码是怎么写的,有哪些注意点?
1.要切谁(要增强的都有什么?)表达式:@Pointcut("execution(* com..ProductService.*(..))")
2.怎么切 (增强的具体内容有什么?)通知方法:前置通知,后置通知,环绕通知
原理是什么?
aop使用动态代理来实现的
默认使用JDK动态代理,会判断目标类是否实现了接口,如果没有实现,则使用cglib动态代理
动态代理有哪几种,分别都是怎么实现的
cglable动态代理
基于继承实现的,他代理目标类的时候会生成一个子类,不能使用final类和fainal方法
jdk动态代理
基于接口实现的,只能代理实现了接口的类,每次方法调用都是使用反射执行的
aop动态代理是spring bean生命周期初始化的时候完成的
aop用的哪些设计模式?
代理模式
责任链模式:代理对象有一堆增强的方法,有一个前后的顺序逻辑,要求按顺序执行,这就是责任链模式(类似拦截器)
拦截器和过滤器的区别
过滤器:servlet容器管理,请求到达服务端之前,会进行一些校验,比如用户信息,身份的验证
拦截器:他是spring框架里实现的,主要是某些请求前后的功能性增强,在处理特定的某些逻辑时候,进行额外的操作
3.Spring的作用域有哪些
singleton------单例
prototype------多例
request----每一个request共享一个bean
session-----每一个session共享一个bean
bean的线程安全问题
prototype
成员变量----线程安全的
每次请求都会创建出一个bean,所以线程安全
静态变量---线程不安全的
singleton
成员变量-----不安全
因为每次请求,都会调用getbean,如果没有这个bean,会创建出bean,等下一次请求,直接用之前创建好的bean
静态变量------不安全
怎么解决单例模式下线程不安全问题?
使用threadlocal,因为本质上造成线程不安全,是因为每一次请求都是同一个bean,操作共享资源造成线程不安全,threadlocl可以保证每一个线程都能拿到自己的数据去操作,数据进行隔离了,从根本上解决了线程不安全问题
4.springboot自动装配原理
核心注解springboot application 点开他 是一个复合注解
有一个enable auto configuration 开启自动配置,点开
有一个auto configuration package 指定的自动配置的包
还有一个import,他是将括号中的auto configuration import selector类和原本的自动装配的类一起加载到容器中
调用auto configuration import selector类的loadmethada方法
会加载metainfo下面的spring.factory配置的那些类,把那些类加载到容器中
5.spring的事物传播机制
1.如果当前存在事物,那就加入,没有的话就创建事物---默认的
2.总是创建一个新的事物
3.如果当前存在事物,那就再嵌套一个事物,没有的话再创建
4.如果当前存在事物,那就加入,如果不存在,也不创建事物
关于网络相关的面试(可以不看),和spring没关系
http和https的区别
http是明文传输,https会对传输的内容通过SSL加密处理,更加安全,并且提供了服务器身份验证
假如说我们有一个网址,在客户端浏览器上面去输入,那前面是 HTPS 开头的,然后是一个域名。而后面是以它的路径资源那些,那么当这个网址敲下去之后,是它有哪些步骤让你返回来能看到它的网页?
首先会根绝DNS解析一下ip
获取到ip后,浏览器会根据ip找到服务器地址,然后简历tcp连接,三次握手
建立连接后,会根据SSL进行加密传输
然后会和服务端发送http请求,通常是get请求
服务器得到请求经过一系列处理后,返回相应参数
浏览器拿到这些相应参数比如html css 资源 进行页面渲染