2022届秋招Java后端高频知识点汇总⑩--Spring
1. 什么是IOC和AOP
IOC:
IOC就是控制反转,指将创建对象的控制权转移给Spring框架来进行管理,如果自己创建的话,需要维护对象与对象之间的依赖关系,很容易造成对象之间的耦合度过高。IOC可以帮助我们维护对象与对象之间的依赖关系,降低对象之间的耦合度。
IOC是通过依赖注入(DI)来实现的,Spring容器负责创建应用程序中的Bean,并通过依赖注入协调这些对象之间的关系。
依赖注入的方法有3种:setter()方法注入、构造方法注入、接口注入
SpringIOC容器的设计主要基于BeanFactory和ApplicationContext两个接口 来创建Bean。
AOP
AOP就是面向切面编程,AOP采用横向抽取机制,将分散在各个方法中的重复代码提取出来,然后在程序编译或运行时,再将这些提取出来的代码织入到需要执行的地方。
AOP实现的关键在于代理模式,AOP代理主要分为静态代理和动态代理。静态代理的代表为AspectJ;动态代理则以Spring AOP为代表。
1.AspectJ是静态代理,也称为编译时增强,AOP框架会在编译阶段生成AOP代理类,并将AspectJ(切面)织入到Java字节码中,运行的时候就是增强之后的AOP对象。
2.Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。
JDK动态代理:这是Java提供的动态代理技术,可以在运行时创建接口的代理实例。Spring AOP默认采用这种方式,在接口的代理实例中织入代码。
2. Spring Bean的生命周期
1.Spring对bean进行实例化,默认bean是单例;
2.Spring对bean进行依赖注入;
3.如果bean实现了BeanNameAware接口,spring将bean的id传给setBeanName()方法;
4.如果bean实现了BeanFactoryAware接口,spring将调用setBeanFactory()方法,将BeanFactory实例传进来;
5.如果bean实现了ApplicationContextAware接口,它的setApplicationContext()方法将被调用,将应用上下文的引用传入到 bean中;
6.如果bean实现了BeanPostProcessor接口,它的postProcessBeforeInitialization()方法(预初始化方法)将被调用;
7.如果bean实现了InitializingBean接口,spring将调用它的afterPropertiesSet()方法,类似的如果bean使用了init-method属性声明了初始化方法,该方法也会被调用;
8.如果bean实现了BeanPostProcessor接口,它的postProcessAfterInitialization()方法(后初始化方法)将被调用;
9.此时bean已经准备就绪,可以被应用程序使用了,他们将一直驻留在应用上下文中,直到该应用上下文被销毁;
3. Spring中Bean的作用域
默认情况下,Bean在Spring容器中是单例的(singleton),可以通过@Scope注解或者配置文件中的scope属性设置Bean的作用域
①singleton:在Spring容器中仅存在一个这个Bean的实例,即一个Bean定义对应一个对象实例。
②prototype:一个bean定义对应多个对象实例。每次调用getBean()时,都会执行new操作,返回一个新的Bean实例。
③request:每次Http请求都会创建一个新的Bean,该作用域仅在当前HTTP Request内有效。
④session:同一个Http Session共享一个Bean,不同Http Session使用不同的Bean。该作用域仅在当前 HTTP Session 内有效。
4. Spring事务的基本实现
Spring事务管理基于AOP
事务管理类DataSourceTransactionManager本质就是一个切面类Aspect
切点就是service层里的方法。
当service里的事务发生异常没有完全执行时,DataSourceTransactionManager的异常增强对事务进行了回滚rollback。
当事务完全执行完毕,DataSourceTransactionManager的后置增强对事物进行了提交commit。
Spring支持两种事务编程模型:
1. 编程式事务
Spring提供了TransactionTemplate模板,利用该模板我们可以通过编程的方式实现事务管理,而无需关注资源获取、复用、释放、事务同步及异常处理等操作。相对于声明式事务来说,这种方式相对麻烦一些,但是好在更为灵活,我们可以将事务管理的范围控制的更为精确。
2. 声明式事务
Spring事务管理的亮点在于声明式事务管理,它允许我们通过声明的方式,在IoC配置中指定事务的边界和事务属性,Spring会自动在指定的事务边界上应用事务属性。相对于编程式事务来说,这种方式十分的方便,只需要在需要做事务管理的方法上,增@Transactional注解,以声明事务特征即可。
5. Spring中使用了哪些设计模式
①工厂模式:Spring通过BeanFactory、ApplicationContext创建Bean对象。
③单例模式:Spring中Bean默认都是单例的。
②代理模式:Spring AOP 功能的实现
④模板方法模式:Spring中jdbcTemplate等以Template结尾的对数据库操作的类,它们就使用到了模板模式。
⑤观察者模式:Spring 事件驱动模型就是观察者模式很经典的一个应用。
⑥适配器模式:Spring AOP 的增强或通知(Advice)使用到了适配器模式,Spring中的AOP中AdvisorAdapter类。Spring MVC中的HandlerAdapter使用了适配器模式。
⑦装饰者模式:Spring中配置DataSource的时候,DataSource可能是不同的数据库和数据源。我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
6. Sping、SpringMVC、SpringBoot的区别
Spring框架就像一个家族,有众多衍生产品例如boot、security、jpa等等;但他们的基础都是Spring 的ioc和 aop,ioc提供了依赖注入的容器,aop解决了面向切面编程,然后在此两者的基础上实现了其他延伸产品的高级功能。
Spring MVC提供了一种轻度耦合的方式来开发web应用;它是Spring的一个模块,是一个web框架;通过DispatcherServlet,ModelAndView和View Resolver,开发web应用变得很容易;解决的问题领域是网站应用程序或者服务开发——URL路由、Session、模板引擎、静态Web资源等等。
7. 注解@Autowired和@Resource有什么区别
1.@Autowired是Spring提供的注解,@Resource是JDK提供的注解。
2.@Autowired是只能按类型注入,@Resource默认按名称注入,也支持按类型注入。
3.@Autowired按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它required属性为false,
如果我们想使用按名称装配,可以结合@Qualifier注解一起使用。
4.@Resource有两个中重要的属性:name和type。
name属性指定byName,
如果没有指定name属性,
当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象,
当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。
需要注意的是,@Resource如果没有指定name属性,并且按照默认的名称仍然找不到依赖对象时,
8. Mybatis怎么通过xml绑定到接口上,具体流程
是通过xml文件中, <mapper> 根标签的namespace属性和具体的查询语句中的id进行绑定的,
即namespace属性的值需要配置成接口的全限定名称,id指向具体的方法
9. 介绍下Spring MVC的执行流程
1.用户通过客户端向服务端发起一个request请求,此请求会被前端控制器(DispatcherServlet)所拦截。
2.前端控制器(DispatcherServlet)请求处理映射器(HandlerMapping)去查找Handler,可以依据XML配置或注解去查找。
3.处理映射器(HandlerMapping)根据请求URL找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成),并返回给前端控制器。
4.前端控制器(DispatcherServlet)请求处理器适配器(HandlerAdapter)去执行相应的Handler(常称为Controller)。
5.处理器适配器(HandlerAdapter)会调用并执行Handler处理器,这里的处理器指的是程序中编写的Controller类,也被称为后端控制 器。
6.Controller执行完毕后会返回给处理器适配器(HandlerAdapter)一个ModelAndView对象,该对象中会包含View视图信息或包含 Model数据模型和View视图信息。
7.处理器适配器(HandlerAdapter)接收到Controller返回的ModelAndView后,将其返回给前端控制器。
8.前端控制器(DispatcherServlet)接收到ModelAndView后,选择一个合适的视图解析器(ViewReslover)对视图进行解析。
9.视图解析器(ViewReslover)解析后,会根据View视图信息匹配到相应的视图结果,反馈给前端控制器。
10.前端控制器收到View视图后,进行视图渲染,将模型数据(在ModelAndView对象中)填充到request域。
10. 介绍一下 MyBatis,它的优点是什么
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。
MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
MyBatis的优点:
1.sql语句与代码分离,存放于xml配置文件中,解除SQL和程序代码的耦合,便于统一管理和优化,并可重用。
2.支持编写动态SQL语句
11. MyBatis中的${}和#{}有什么区别
#{}:在预编译时,会把参数部分用一个占位符?代替,传入的内容会被作为字符串,被加上引号,安全性高,可以防止sql注入。
${}: 传入的内容会直接拼接,不会加上引号,可能存在sql注入的安全隐患。
所以能用#{}的地方就用#{}, 但是诸如传入表名,需要排序的时候order by 字段 的 “字段名”的时候可以用${}.
什么是SQL注入?
所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令。
12. MyBatis缓存
MyBatis的缓存分为一级缓存和二级缓存
①MyBatis的一级缓存是SqlSession级别的缓存,当在同一个SqlSession中执行两次相同的SQL语句时,会将第一次执行查询的数据存入一级缓存中,第二次查询时会从缓存中获取数据,而不用再去数据库中查询,从而提高了查询性能。但如果SqlSession执行insert、delete和update操作,并提交到数据库或者SqlSession结束后,这个SqlSession中的一级缓存就不存在了。
②MyBatis的二级缓存是SqlSessionFactory级别的缓存,由同一个SqlSessionFactory对象创建的sqlsession共享其缓存。
MyBatis提供了一级缓存和二级缓存:
一级缓存:也称为本地缓存,用于保存用户在一次会话过程中查询的结果,用户一次会话中只能使用一个sqlSession,一级缓存是自动开启的,不允许关闭。
二级缓存:也称为全局缓存,是mapper级别的缓存,是针对一个表的查结果的存储,可以共享给所有针对这张表的查询的用户。也就是说对于mapper级别的缓存不同的sqlsession是可以共享的。