Spring概述
Spring是一个Java开发框架,可以简化java程序的开发。有三个核心组件,IOC(控制反转)、DI(依赖注入)、AOP(面向切面编程)。
IOC
概念:
控制反转,将创建对象的权利交给Spring让Spring来帮我创建对象,我们只需要在使用的时候在从容器中获取即可。
IOC容器有哪些?
-
ClassPathXmlApplicationContext
-
FileSystemXmlApplicationContext
-
AnnotationConfigApplicationContext
-
BeanFactory
ApplicationContext和BeanFactory的区别?
ApplicationContext和BeanFactory都是Spring的容器。
区别:BeanFactory是底层接口,ApplicationContext是派生接口(功能更强大)。BeanFactory是懒加载,使用的时候才会创建Bean。内存不足时,可以使用BeanFactory。ApplicationContext默认在容器初始化的时候就加载所有的bean,好处是使用的时候拿来即用,无需等待,缺点是比较耗费内存。
BeanFactory和FactoryBean的区别?
BeanFactory是Spring容器,FactoryBean是一个特殊的bean,用于创建bean,创建出来的bean会放在容器中。
bean标签中有哪些属性?
<bean id="" class="" name="" scope="" init-method="" desctory-method="" lazy-init="" autowire="">
Spring中的单例Bean是线程安全的吗?
不安全。但是spring中的bean是无状态的,也就是不存储数据,所以在某种程度上来讲是线程安全的。
如何解决线程安全问题?
-
把bean的作用域改为非单例 prototype
-
把共享变量放到ThreadLoacl中,ThreadLoacl是线程私有变量,线程间隔离,也可以解决线程安全问题。
简单描述下Spring容器中bean的生命周期?
BeanDefinition -> 实例化 -> 依赖注入 -> 初始化 -> 放到容器中使用 -> 销毁
BeanDefinition是bean定义。描述的是 这个bean的类型,即这个bean的名字、有哪些属性、有哪些构造函数、有哪些方法。
-
先通过配置文件或者注解拿到所有的BeanDefinition,并放到BeanDefinitionMap中
-
从BeanDefinitionMap中拿到bean定义并进行实例化 new
-
依赖注入,给容器中bean中的属性赋值
-
初始化,给属性赋值(成员变量等)
-
初始化完成后,bean真正创建完成,就可以把bean放到Spring容器中,ConcurrentHashMap,我们使用的时候就可以通过getBean来获取bean
-
容器销毁的时候,bean也会跟着销毁
DI
概念:
依赖注入,给容器中bean的属性赋值。
依赖注入的方式有哪些?
构造器注入
<constructor-arg name="" ref="" / value="">
setter注入
<property name="" ref="" / value="">
AOP
概念:
面向切面编程。把公共代码抽取出来,并在不影响/修改原始代码的基础上对方法进行功能增强。
连接点:所有可以被功能增强的方法都叫连接点。
切入点:进行了功能增强的方法就叫切入点。
通知:共性功能。
通知类:通知所在的类就叫通知类。
切面:切入点+通知就是切面。描述的是:在哪些方法上进行什么功能增强
AOP底层原理?
动态代理。在程序运行期间动态生成一个代理对象,当调用到原始方法时,真正执行的是代理对象的代理方法。
动态代理的实现方式有两种:
①基于JDK的动态代理(反射)
②基于CGLib的动态代理(继承)
5种通知类型:
前置通知:@Before
后置通知:@After
环绕通知:@Around
异常后通知:@AfterThrowing
返回后通知:@AfterReturning(不报错的前提下)
注解
Spring中使用过的注解:
定义bean:
@Component 定义Spring管理Bean(也就是将标注@Component注解的类交由spring管理)
@Controller @Controller标识的类,该类代表控制器类(控制层/表现层)。
@Service 标记当前类是一个service类,加上该注解会将当前类自动注入到spring容器中(业务逻辑层)@Service标识的类中的方法可以继续调用@Resposity标识的接口实现类(Dao层/持久层)
@Repository @Resposity标识的接口实现类(Dao层/持久层)
依赖注入:
@Autowired 按类型自动装配
(Autowired作用范围:构造器、方法、参数、成员变量、注解)
@Qualifier 按名称自动穿配(无法单独使用,需要配合Autowired)
@Resource 默认按类型自动装配,也可按名称自动装配;相当于(@Autowired+@Qualifier)
@Value 简单类型自动装配
定义第三方bean:
@Bean
配置类注解:
@Configuration 从Spring3.0,@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。
@Import @Import注解是用来导入配置类或者一些需要前置加载的类.
@PropertySource @PropertySource注解用于指定资源文件读取的位置,它不仅能读取properties文件,也能读取xml文件,并且通过YAML解析器,配合自定义PropertySourceFactory实现解析YAML文件。
@ComponentScan @ComponentScan注解一般和@Configuration注解一起使用,主要的作用就是定义包扫描的规则,然后根据定义的规则找出哪些需类需要自动装配到spring的bean容器中,然后交由spring进行统一管理。
bean的作用范围和生命周期:
@Scope @Scope默认是单例模式,即scope="singleton"。@Scope注解是springIoc容器中的一个作用域,在 Spring IoC 容器中具有以下几种作用域:基本作用域singleton(单例)、prototype(多例),Web 作用域(reqeust、session、globalsession),自定义作用域
@PostConstruct 会在服务器加载Servlet的时候运行,并且只会被服务器执行一次,具体运行时期是在构造函数执行之后,init()初始化方法之前。@PostConstruct注解的方法在项目启动的时候执行这个方法,也可以理解为在spring容器启动的时候执行,可作为一些数据的常规化加载
执行顺序:
其实从依赖注入的字面意思就可以知道,要将对象p注入到对象a,那么首先就必须得生成对象a和对象p,才能执行注入。所以,如果一个类A中有个成员变量p被@Autowried注解,那么@Autowired注入是发生在A的构造方法执行完之后的。
如果想在生成对象时完成某些初始化操作,而偏偏这些初始化操作又依赖于依赖注入,那么就无法在构造函数中实现。为此,可以使用@PostConstruct注解一个方法来完成初始化,@PostConstruct注解的方法将会在依赖注入完成后被自动调用。
Constructor(构造方法) >> @Autowired(依赖注入) >> @PostConstruct(注释的方法)
@PreDestroy 会在服务器卸载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet的destroy()方法,会在destroy()方法之后运行,在Servlet被彻底卸载之前。
事务
Spring事务的作用?
保证业务层方法同成功同失败
如何添加事务?
-
@Transactional
-
在主配置类上添加 @EnableTransactionManager
-
把事务管理器交给Spring管理 PlateformTransactionManagement
事务传播行为的作用?
用于解决业务层方法相互调用所产生的事务问题,描述的是:事务协调员是否要和失物管理员同成功同失败。
事务传播行为有哪些?
默认、新建、支持、不支持
SpringMvc
SpringMvc注解有哪些?
@RestController
@RequestMapping
@PostMapping
@DeleteMapping
@PutMapping
@GetMapping
@PathVariable
@RequestParam
@RequestBody
@ResponseBody
过滤器和拦截器的区别?
*使用范围上:过滤器的适用范围是web容器,拦截器的使用范围是Spring容器
*适用对象上:过滤器过滤的是servlet,拦截器拦截的是Controller
*原理上:过滤器的原理是调用(回调),拦截器的原理是反射
如何统一处理异常?
-
自定义异常
-
类上@RestControllerAdvice、方法上@ExceptionHandler
SpringMvc的执行流程?
-
前端发起请求 到DispatcherServlet
-
DispatcherServlet 访问 处理器映射器 把前端请求路径 转换成 后端Handler 并返回
-
DispatcherServlet 访问 处理器适配器 找到合适的Handler(Controller)处理逻辑并返回ModelAndView
-
DispatcherServlet 访问 视图解析器 解析ModelAndView并返回View对象
-
DispatcherServlet 把 view对象渲染成 jsp页面 并返回给前端
处理器映射器:把前端请求的url 转换成 后端Handler
处理器适配器:找到合适的Handler并执行,返回ModelAndView
视图解析器:把ModelAndView解析成视图view
MybatisPlus
标准开发接口?
insert
deleteById
updateById
selectById
selectList
selectPage
条件构造器?
QueryWrapper
LambdaQueryWrapper
条件查询都有哪些方法?
eq(相等/同)
lt(小于)
le(小于等于)
gt(大于)
ge(大于等于)
between (两条件之间)
like (模糊查询/包含)
兼容性处理:
类名和表名映射:@TableNam1
属性名和字段名映射:@TableFiled(value="")
设置不查询字段:@TableFiled(select=false)
设置实体类字段在数据库中不存在:@TableFiled(exist=false)
DML:
id生成策略:@TableId auto/Assign
逻辑删除:@TableLogic
乐观锁:@Version
SpringBoot
SpringBoot提供了哪些核心功能?
起步依赖
自动配置
jar包快速启动
SpringBoot核心注解是什么?由哪几个注解组成?
@SpringBootApplication
@SpringBootConfiguration
@ComponentScan
@EnableAutoConfiguration
SpringBoot支持哪些配置文件?加载顺序是什么样的?
properties > yml > yaml
SpringBoot读取配置文件的三种方式?
@Value
Environment
实体类 @ConfigurationProperties(prefix="")