目录
✅Spring中的 bean 和 new 的对象有什么区别?
✅什么是Spring?你的理解是什么?
是一个轻量级的,开源的,一站式的Java开发框架,为简化企业级开发而生
✅Spring的优缺点
优点:
轻量级,开源的,简单,IOC和AOP
缺点:
配置麻烦,很多都是模板化配置,管理很多依赖
✅解释一下IOC和AOP
IOC:
控制反转,把项目中创建对象的权利反转给Spring框架,由Spring框架统一管理项目中的对象,把由Spring框架生成的对象称为一个bean对象,Spring可以对对象进行功能上的增强。例如Service层可以添加日志、事务管理。
AOP:
面向切面编程,使用动态代理的方式,为目标对象提供代理对象,在不修改目标类中的代码时,为目标类添加额外的功能。将额外的功能横切到目标类中。
✅IOC和DI的区别?
IOC上一问回答过了
DI:
Dependency Injection,即依赖注入,@Autowired,在IOC的基础上,把对象注入到需要的地方
✅Spring中管理 / 注入对象的方式
xml配置方式,注解方式
属性注入(Set方法注入),构造方法注入
✅常用注解
▪ 控制层 @RestController
▪ 数组访问层 @Repository
▪ 基本组件 @Component
......(其余参考文档)
✅Spring中的 bean 和 new 的对象有什么区别?
bean对象是由Spring框架创建的,根据我们的配置可以进行功能上的增强。配置比如说事务、日志、统一异常处理等。
自己new的对象就是最原始的对象,没有任何功能增强。
✅AOP中的属于有哪些?通知有哪些?
▪ 属性
连接点:类中可以被增强的方法
切入点:类中实际被增强的方法
通知:给切入点添加的功能
目标:被增强的类
代理:代理对象
▪ 通知类型
前置通知:方法执行前执行
后置通知:在方法执行后执行,即使出现异常也会执行
返回通知:也是在方法执行后执行,但一旦出现异常就不会执行
异常通知:出异常时执行
环绕通知:可以实现以上四个通知
✅谈谈Spring事务管理,实现方式有几种,原理是什么?
事务是数据库的特性,Spring事务管理只是Spring框架对事务开启,提交,回滚进行管理
▪ 编程式事务:需要在代码中自己提交,回滚
▪ 声明式事务:在类、方法上声明即可,使用@Transactional(rollbackFor = Exception.class)
使用动态代理对象
✅声明式事务哪些场景下会失效?
▪ @Transactional用在非public方法上
▪ 方法中的异常被捕获了,认为方法没有异常
▪ 方法中出现编译期异常,还是会提交事务,可以将 rollbackFor = Exception.class 这样所有的异常都会回滚
▪ 数据库引擎不支持事务,mysql中只有InnoDB引擎支持事务的
✅SpringMVC运行流程
✅Servlet的过滤器与Spring拦截器区别?
✅Spring和SpringBoot关系
SpringBoot是对Spring框架的搭建进行封装,简化了搭建过程,不是替代Spring的,底层仍然还是Spring
✅Spring中Bean的生命周期
宏观上来讲可分为五个阶段:
▪ 实例化 Instantiation
▪ 属性赋值 Populate (依赖注入)
▪ 初始化 Initialization (最关键的,根据我们各种的注解配置,在这一步进行落地实现)
▪ 将bean对象放到容器中,使用
▪ 销毁 Destruction
✅Spring中Bean的线程安全的吗?
这个问题需要分情况回答,要根据使用场景
单例Bean
▪ Spring中的Bean如果是单例的,始终只创建了一个对象,所有请求共用同一个对象,那么对该单例对象中的成员变量也就只有一份,所有请求共享。
▪ 在多用户访问时,可能出现问题,还有种情况就是每个请求中都拥有一个属于自己的成员变量使用。
▪ 所以单例Bean在使用时就有可能存在线程安全的问题
原型Bean
▪ 原型Bean每次请求都会创建新的对象,不会存在线程安全的问题
单例Bean线程安全问题解决:
▪ 如果成员变量是共享的,多线程操作时,如++等操作需要进行加锁控制
▪ 如果每个请求在中都需要一个属于自己的成员变量,可以把单例Bean改为原型,也可以使用ThreadLocal,为每次请求提供变量副本。
单例Bean又分为:
▪ 有状态的Bean。就是有成员变量,而且成员变量可以存储数据,就是可能在多线程操作时会出现问题
▪ 无状态的Bean。像通过@Autowired 注入的对象不用于存储数据,只是调方法,每次请求中的参数数据都是隔离的,多线程也是安全的
✅Bean依赖循环
在Spring中,如果使用@Autowired自动注入,在创建A对象时就需要为它关联的B对象注入值,这时就需要去创建对象B,创建B时又需要为关联的A注入值,但是此时A还没创建完成,形成死循环。
class A{
@Autowired
B b;
}
class B{
@Autowired
A a;
}
public static void main(String[] args){
A a = new A();
B b = new B();
}
✅Spring中是如何解决循环依赖的问题的?
Spring中使用三级缓存来解决循环依赖问题
▪ 一级缓存(singletonObject),一级缓存对象,主要存储创建,初始化完成的Bean对象
▪ 二级缓存(earlySingletonObject),主要存储实例化完成,但还未初始化完成的半成品对象。
▪ 三级缓存(SingletonFactories),主要存储创建对象的工厂对象,创建A时,还有一个创建A的 工厂对象
过程描述:创建A时,需要用到B,A创建了一半,把它存放到二级缓存中,把创建A工厂放到三级缓存中,把半成品A注入到B中,B完成了创建,把B放到了一级缓存中,再把B注入到A中,A对象完成了创建。
✅SpringBoot自动装配原理
从启动类说起
@SpringBootApplication 注解标签,里面包含了三个注解标签
@SpringBootConfiguration
@EnableAutoConfiguration //自动配置
@ComponentScan( //扫描启动类所在的包下的类
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
约定大于配置