Spring知识点总结
目录
1.什么是spring?你对spring的理解?
2.spring的优缺点?
3.解释一下IOC和AOP?
4.IOC和DI的区别?
5.spring中管理对象注入的方式?
6.自动注入的注解有哪些?
声明bean的注解
Bean的生命周期属性
注入bean的注解
7.Spring中的bean对象和new出来的有什么区别?
8.AOP的术语有哪些?通知有哪些?
9.Spring中AOP的实现方式有哪些?
10.谈谈Spring中的事务管理,实现方式有哪几种,原理是什么?
11.Spring中声明式事务在什么场景下会失效?
12.SpringWeb(SpringMVC)的运行流程?
13.Servlet的过滤器和Spring拦截器的区别?
14.Spring和SpringBoot的关系?
15.Spring中常用的注解?
16.SpringBean的生命周期?
17.Spring中的bean是线程安全的吗?
18.Bean循环依赖?
什么是bean循环依赖问题?
spring中如何解决循环依赖问题?
过程
19.SpringBoot自动装配原理?
1.什么是spring?你对spring的理解?
spring是一个轻量级的,一站式的java后端开发框架,为简化企业级开发产生的。
2.spring的优缺点?
优点:轻量级,开源的,简单,IOC和AOP
缺点:配置麻烦,很多都是模板化的配置,管理很多依赖。
3.解释一下IOC和AOP?
IOC:控制反转。就是将创建对象的操作交给spring去完成,由spring统一管理项目中的对象。把由spring框架生成的对象成为一个bean对象,spring可以对对象进行功能上的增强。
AOP:面向切面编程。使用动态代理方式,为目标类提供代理对象,在不修改目标类中的代码时,为目标类提供额外的功能,将额外的功能横切进目标类当中。
AOP的应用场景:spring事务,全局异常处理,配置类,日志记录,缓存管理等。
4.IOC和DI的区别?
IOC是控制反转。
DI(Dependency Injection):依赖注入,在IOC的基础上将对象注入到需要用的地方。
5.spring中管理对象注入的方式?
xml配置注入,注解注入,属性注入,构造方法注入。
6.自动注入的注解有哪些?
声明bean的注解
@RestController、@Service、@Repository都可以称为@Component
@Component:基本组件
@RestController:控制层
@Service:服务层
@Repository:数据访问层
Bean的生命周期属性
@Scope设置类型包括:设置Spring容器如何创建Bean实例。
singleton:单例,一个spring容器中只能有一个bean实例,默认模式。
protetype:每次调用创建一个新的bean实例。
request:web项目中,给每个http request新建一个bean。
注入bean的注解
@Autowried:由Spring提供
@Qualifier:当有多个同一类型的Bean时,可以用@Qualifier(“name”)来指定,可以与@Autowried配合使用。
@Resource:由Java提供。
7.Spring中的bean对象和new出来的有什么区别?
bean对象是由Spring框架进行创建的,根据我们的配置(事务,日志,统一异常处理等)进行功能上的增强。
new出来的对象就没有这些额外的功能。
8.AOP的术语有哪些?通知有哪些?
连接点:类中可以被增强的方法
切入点:类中实际被增强的方法
通知:给切入点添加新的功能
目标:被增强的类
代理:代理对象
通知类型:
前置通知:在方法执行前执行。
后置通知:在方法执行后执行。
返回通知:在方法执行后执行,一旦出现异常就不会执行了。
异常通知:在出现异常时执行。
环绕通知:可以实现前置,后置,返回,异常通知。
9.Spring中AOP的实现方式有哪些?
xml配置方式
注解方式
10.谈谈Spring中的事务管理,实现方式有哪几种,原理是什么?
事务是数据库的特性,Spring事务管理,只是Spring框架对事务开启,提交,回滚进行管理。
Spring中事务管理分为:
编程式事务管理:开始事务,提交事务,回滚事务都使用java来写。
声明式事务管理:只需要在类,方法前面使用@Transactional(rollbackFor=Exception.class)使用动态代理对象即可。
11.Spring中声明式事务在什么场景下会失效?
声明式事务失效的场景:
1.注解@Transactional加在了非public的方法上
2.方法中的异常被捕获了,认为方法没有异常
3.方法中出现编译器异常,还是会提交事务,可以将rollbackFor=Exception.class这样所有的异常都会回滚。
4.数据库不支持事务,Mysql中只有innodb引擎支持事务。
12.SpringWeb(SpringMVC)的运行流程?
用户发送出请求到前端控制器 DispatcherServlet。
1.DispatcherServlet 收到请求调用 HandlerMapping(处理器映射器)。
2.HandlerMapping 找到具体的处理器(可查找 xml 配置或注解配置),生成处理器对象及处理器拦截器(如果有),再一起返回给 DispatcherServlet。
3.DispatcherServlet 调用 HandlerAdapter(处理器适配器)。
4.HandlerAdapter 经过适配调用具体的处理器(Handler/Controller)。
5.Controller 执行完成向前端响应结果。
13.Servlet的过滤器和Spring拦截器的区别?
过滤器是Servlet中定义的,拦截器是Spring中定义的。
Spring 中的拦截器与过滤器有着本质的区别,过滤器是 servlet 规范中定义并实现的,在进入servlet 之前截获请求.而拦截器是 spring 中定义的一种拦截机制,是对进入到处理器的请求进行拦截。
过滤器可以拦截所有进入到java后端的请求,而拦截器只能拦截进入Controller层的请求。
14.Spring和SpringBoot的关系?
SpringBoot只是对与Spring框架的搭建进行了封装,简化了搭建过程,不是代替Spring的,底层依然还是Spring。
15.Spring中常用的注解?
@SpringBootApplication:启动类上面使用,包括:
@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan 这三个注解。
@SpringBootConfiguration:表明当前类是一个SpringBoot的配置类,本质上是一个@Configuration注解。
@EnableAutoConfiguration:最核心的注解,启用SpringBoot中的自动配置机制,根据项目依赖自动配置Spring应用上下文。
@ComponentScan:启用组件扫描,自动发现spring容器中的组件(如@Controller,@Service等注解下的类)
@RestController,@Service,@Repository,@Component,@Configuration等等。
16.SpringBean的生命周期?
宏观上来讲,springbean分为5个周期:
1.实例化--Instantiation
2.属性赋值--Populate (依赖注入)
3.初始化--Initialization (最关键的 根据我们各种的注解配置,在这一步进行落地实现)
4.将bean对象放在容器当中使用
5.销毁--Destruction
17.Spring中的bean是线程安全的吗?
spring中的bean如果是单例,始终只创建了一个对象,所有请求公用一个对象,那么该单例对象中的成员变量也就只有一份,所有请求共享。
在多用户同时访问的时候就会出现问题,还有种情况,就是想每个请求中,都用于一个属于自己的成员变量使用,所以单例bean使用时,就有可能存在线程安全问题。
原型bean每次请求都会创建新的对象,不会存在线程安全问题。
单例bean线程安全问题解决:如果成员变量是共享的,多线程(请求)操作时,如++等操作,进行加锁的控制. 如果每个请求中,都需要一个属于自己的成员变量:
1.把单例bean改成原型bean.
2.使用ThreadLoacl为每次请求提供变量副本
ThreadLocal<Integer> threadLocal = new ThreadLocal<>(){@Overrideprotected Integer initialValue() {return 1;}};
单例bean又分为:
有状态bean, 就是有成员变量,而且成员变量可以存储数据,就有可能多线程操作出问题。
无状态bean @Autowired OrderService orderService; 注入的这种对象,不用于存储数据,只是调方法,每次请求中的参数数据都是相互隔离的。
18.Bean循环依赖?
什么是bean循环依赖问题?
class A{@AutowiredB b;
}class B{@AutowiredA a;
}public static void main(String[] args) {A a = new A(); //创建A对象时,关联对象b为nullB b = new B(); //创建B对象时,关联对象a为null
}
虽然A,B之间相互关联,但是创建对象时没有任何问题.
A类中注入B类,B类中又注入A类,导致两边都注入不了,这就是循环依赖问题。
spring中如何解决循环依赖问题?
spring中使用三级缓存来解决循环依赖问题。
三级缓存其实就是使用三个map来存储不同的对象。
一级缓存singletonObjects:主要存储创建,初始化完成的bean对象。
二级缓存earlySingletonObjects:主要存储实例化完成,但还未初始化的半成品对象。
三级缓存singletonFactories:主要存储创建对象工厂对象,eg:创建a时,还有一个创建a的工厂对象。
过程
创建A时,需要用到B,这时A创建了一半,将A放在二级缓存当中,再将创建A的工厂对象放在三级缓存当中,接着去创建B,B创建好之后,将B放在一级缓存当中,再把B注入进A,接着创建A完成。
19.SpringBoot自动装配原理?
这就要从启动类说起了:
@SpringBootApplication 是springboot中最核心的注解
@MapperScan("com.ffyc.aiserver.dao")
public class AiserverApplication {public static void main(String[] args) {//加载启动类SpringApplication.run(AiserverApplication.class, args);}}@SpringBootApplication 注解标签,里面包含了三个注解标签
@SpringBootConfiguration
@EnableAutoConfiguration 自动配置
@ComponentScan( 扫描启动类所在的包下的类excludeFilters = {@Filter(type = FilterType.CUSTOM,classes = {TypeExcludeFilter.class}
), @Filter(type = FilterType.CUSTOM,classes = {AutoConfigurationExcludeFilter.class}
)}
)@EnableAutoConfiguration 自动配置@Import({AutoConfigurationImportSelector.class}) 根据pom.xml中配置的相关依赖,进行选择性的加载,读取相关依赖的配置类.
@SpringBootApplication注解当中的@EbableAutoConfiguration起重大作用。