目录
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起重大作用。