目录
2.4 说说BeanFactory和ApplicationContext
5.2 Spring MVC Restful风格的接口的流程是什么样的呢?
6.4 了解Springbootapplication注解吗
6.5 为什么springboot在启动时能找到main方法上的springbootapplication注解
一 Spring 基础
1.1 Spring是什么
spring是一个控制反转和面向切面的轻量级开发框架,Spring支持IOC和DI,Spring的核心是一个大的工厂容器,可以维护所有对象的创建和依赖的关系,Spring工程用于生产Bean,并管理Bean的生命周期,实现高内聚低耦合的设计理念。
Spring提供了面向切面编程,可以方便实现对程序进行权限拦截,运行监控等切面功能
声明式事务的支持,快捷测试的支持,spring对Junit提供支持,可以通过注解便捷的测试
1.2 Spring有哪些模块
Spring core continer,Spring web,Spring MVC,Spring DAO,Spring AOP
1.3 Spring有哪些常用的注解呢
web:controller、restcontroller、getMapping、PostMapping、deletmapping、restrequest、requestbody、responsebody、pathvariable
容器:component、service、value、scope、autowired、configuration、bean
aop:aspect、after、before、around、pointcut
事务:transactional
1.4 spring中有哪些设计模式
工厂模式、单例模式、策略模式、代理模式、模板模式、观察者模式、适配器模式
1.5 Spring容器和web容器之间的区别?
Spring 容器是一个巨大的工厂容器用来管理bean的生命周期以及对象之间的依赖关系
web容器也是servlet容器,用于运行java web应用程序的服务器环境。
Spring MVC是Spring框架的一部分,专门用于处理web请求,基于MVC设计模式model-view-controller
二 IOC
2.1 什么是IOC
IOC也称控制反转,就是由容器来控制管理对象的生命周期和对象之间的依赖关系,一般我们编写程序创建对象是需要手动new一个对象出来,IOC的思想是对象不用程序员手动创建,容器帮我们创建,需要时直接从容器中拿出来。
也就是说控制对象生命周期的不再是引用它的对象,而是容器,这就叫控制反转。
2.2 什么是DI
IoC是思想,DI是IoC的实现,控制反转这个词太广泛,不能很好的解释spring框架的实现,于是就想到了一个新的名词:依赖注入
2.3 为什么要用IoC呢
IoC降低了对象这间的耦合度,使编程更加灵活,更易于维护
在平时的java开发中,如果实行某一功能,至少需要两个以上的对象来协作完成,在没Spring之前,每个对象需要合作对象时候需要手动new一个,也就是A、B之间存在了一种耦合关系。有了Spring之后,创建B的工作就由Spring来完成,A告诉Spring需要B,则Spring就从容器中取出B给A来使用,不用A自己new一个了。
2.4 说说BeanFactory和ApplicationContext
BeanFactory主要负责配置、创建、管理Bean,主要的方法是getBean,为Spring提供了基本的依赖注入支持
ApplicationContext是BeanFactory的子接口,继承了hierachicalbeanfactory,listablebeanfactory,是 BeanFactory的自动挡版本,它会在启动时预先创建和配置所有的单例bean,支持JDBC框架继承、内置面向切面AOP的支持、可以配置声明式事务
2.5 Spring容器启动阶段会干什么吗?
Spring的工作过程可以分为两个阶段:容器启动阶段和Bean实例化阶段
容器启动阶段:
加载Bean的配置文件
分析Bean的信息
把Bean装配到BeanDefinition
2.6 Spring中Bean的实例化方式
构造方法方式:
在类上使用component注解,通过构造方法注入依赖
静态工厂的方式:
Bean是由一个静态方法创建的,而不是直接通过构造方法
public class BeanService{
private static BeanService beanservice = new BeanService();
private BeanService(){};
public static BeanService creatBeanService{
return beanservice;
}
}
实例工厂方法实例化方式:
实例工厂方法依赖于某个类的实例来创建Bean。
public class BeanService{
public ClientService creatBeanService{
return new ClientService;
}
}
FactoryBean接口实例化方式
通过实现FactoryBean接口,自定义实例化逻辑
2.7 说一下Bean的生命周期
BeanFactory和ApplicationContext实例化时机不一样,前者是第一次getBean()的时候才会实例化Bean,后者在启动容器时预先创建并加载所有的Bean,包含了BeanFactory的所有功能,还增加了国际化支持,事件传播等功能。
Bean的生命周期分为四个阶段:实例化、属性赋值、初始化、销毁
实例化:创建Bean实例的过程,就是new一个对象
属性赋值:根据Bean中的配置信息,通过反射机制为Bean的属性赋值
初始化:执行自定义的初始化逻辑,比如检查必要的属性是否以及设置,开启资源等
使用@postconstruct注解的方法
实现initializingbean接口的afterproperiesert方法
自定义初始化方法需要通过注解@Bean(initMethod = “方法名”)
销毁
使用@predestroy注解的方法
实现disposablebean接口的destroy方法
自定义销毁方法在配置类中指定销毁bean(destroymethod=‘方法名’)
2.8 Bean定义和依赖有哪些方式
配置文件方式:xml、properties
注解:spring会完成扫描注解,完成依赖注入的关系
2.9 有哪些依赖注意方法
构造方法注入
属性方法注入
工厂方法注入:静态工厂和非静态工厂方法
2.10 Spring有哪些自动装配的方式?
byType、byName、constructor、autodetect
constructor与bytype类似,只针对构造函数注入,如果Boss中有一个构造函数包含一个Car类型,会自动将这个Bean作为Boss构造函数的入参
autodetect:自动装配如果bean只有默认构造函数就用Bytype,否则用constructor
2.13 spring中bean的作用域有哪些
singleton:Bean以单例的方式存在,spring默认的作用域
prototype:每次从容器调用Bean时候,都会返回一个新的实例
web应用中适用的:
request:每次请求会产生一个新的Bean,仅在当前请求内有效
session:同一个session共享一个bean
globolsession
2.14 Spring中的Bean存在线程安全问题吗
如果Bean是无状态的,也就是没有成员变量,那么这个单例Bean是线程安全的。比如Spring MVC中的Controller、Service、DAO
如何解决Bean的线程安全问题呢
使用线程局部变量、尽量使用无状态的Bean、同步访问使用Synchronized关键字、将Bean的成员变量保存在Threadlocal当中
2.15 说说依赖循环
A依赖B、B依赖A、或者C依赖C就成了依赖循环
依赖循环只发生在singleton作用域的Bean之间,如果是Prototype作用域的Bean就会抛出异常
Spring不可以解决哪些情况的循环依赖
依赖注入方式:AB均采用构造方法注入方式、B中注入A是setter注入,A中注入B是构造器注入
2.16 Spring如何解决循环依赖呢?
用三级缓存
一级缓存存储已经初始化、实例化、注入的bean
二级缓存存储已经实例化完成的bean实例
三级缓存存储创建对象的对象工厂
三级缓存解决循环依赖的过程是什么样的
A依赖B、B依赖A
创建A、实例化的时候把A的对象工厂放入三级缓存、表示A已经开始实例化了
A注入属性时发现需要B,此时B还没被创建过来,所有去实例化B
B注入属性时候发现依赖A、就从换从里找A对象,从一级到三级查询,可以从三级缓存中通过对象工厂拿到A,虽然A不太完善但是存在,就把A放入二级缓存,同时删除三级缓存的A,此时B已经实例化并且初始化完成了,就把B放入一级缓存,接着A继续属性赋值,从一级缓存中拿到B对象,此时A也完成放入一级缓存
2.17 为什么要三级缓存?二级不行吗
不行,主要是为了生成代理对象。如果没有代理的情况下,使用二级缓存解决依赖循环也是可以的。三级缓存中存放的是生产具体对象的匿名内部类,获取object时候,可以生成代理对象,也可以返回普通对象。使用三级缓存就保证无论什么时候都使用的是一个对象。
如果只有二级缓存,在二级缓存中存放一个普通Bean对象,在Bean初始化过程中,通过后置处理器生成代理对象后,覆盖了二级缓存中的普通对象,可能导致读取的Bean对象不一致。
2.18 autowired的实现原理
实现autoweired的关键是 autowiredannotationBeanpostprocessor
bean创建的过程中一共有12个后置处理器
实现autoweired功能也是通过后置处理器完成的,在创建Bean的过程中,会调用docreateBean方法,在这个方法中会调用populateBean方法进行属性填充,populatebean方法中调用了两次后置处理器,第一次判断是否需要进行属性填充,如果需要继续执行,然后调用autowiredannotationbeanpostprocessor中的方法,完成对autowired注解解析,然后实现自动装配。
3 AOP
3.1 什么是AOP
AOP面向切面编程,就是把业务逻辑中相同的代码抽离到一个单独的模块中,让业务逻辑更加清晰
其核心概念包括:
切面,连接点,切点,通知,目标对象,引入,织入
5种环绕方式:before、after、around、afterreturning、afterthrowing
多个切面环境下可使用order指定先后顺序,数字越小,优先级越高
3.2 说说JDK动态代理和CGLB动态代理
JDK动态代理必须满足类实现某个接口,只能代理实现了某个接口的类
CGLB动态代理是基于继承的动态代理,可以实现没有实现接口的类
选择CGLB动态代理还是JDK动态代理
如果目标对象没有实现任何接口,则只能使用CGLIB代理,如果实现了某个接口通常首先JDK动态代理。
JDK动态代理不需要引入额外的库,CGLIB需要引入CGLIB库
CGLIB动态代理在生成过程中可能消耗更多资源,但在运行时具有较高的性能。
四 事务
4.1 事务的种类
声明式事务和编程式事务
编程式事务用TransactionTemplate来实现,需要显示执行事务
声明式事务是建立在AOP之上的,本质是通过AOP功能,对方法前后进行拦截,在根据执行情况进行提交或回滚
4.2 Spring的事务隔离级别
1.数据库默认隔离级别,Mysql是可重复读
2,读未提交,会导致脏读
3. 读已提交,解决脏读,但仍然可能发送不可重复度和幻读
4,可重复读
5,串行化
4.3 事务传播行为
1.如果当前没有事务就创建一个事务,如果存在一个事务就加入该事务中
2,支持当前事务,如果有则加入,如果没有则以非事务的方式执行
3,强制必须有事务,如果外面有事务则加入,没有则抛出异常
4,新建事务,如果存在当前事务,
5.not support,以非事务方式运行,当前存在事务则抛出异常
6,nested 嵌套事务
4.4 声明式事务在哪些情况下会失效?
Transactional应用在非public修饰的方法上
因为是在AOP代理时,事务拦截器在目标前后会进行拦截,会检查目标方法修饰符是否是public,不是则不会获取注解信息
Transactional注解属性propagation设置错误
事务的传播行为设置,sport,not spport,neve
robackfor设置错误
spring默认抛出unchecked异常或者error才回滚事务
同一个类中调用,导致事务失效
只有当前事务被当前类以外的代码调用时,才会由Spring生成的代理对象来管理。
五 MVC
5.1 Spring MVC的核心组件
前置控制器,相当于总指挥控制其他组件的执行
处理器,完成具体的业务逻辑,相当于sevlet
处理器映射器,前置控制器接受到请求后,通过处理器映射器找到相应的Handler
处理器拦截器,一个接口,需要完成一些拦截可以实现该接口
处理器执行链,包括handler和处理器拦截器
处理器适配器,处理器执行业务方法之前,需要进行一系列操作,包括表单数据验证和数据类型转换,这些操作是处理器适配器完成的,然后执行不同的handler
modelandview:装载了模型数据和视同信息,作为handler的返回结果,返回给前端控制器
viewResolver:将逻辑视图转换为物理视图,最终渲染结果响应给客户端
5.2 Spring MVC Restful风格的接口的流程是什么样的呢?
Restful 接口,响应格式是json,通常用到了一个常用的注解 @responsebody
工作流程:
前端发出一次请求,被前端控制器接受
前端控制器通过处理器映射器得到处理器
前置控制器通过处理器适配器执行handler
handler执行完成后modelanview为null,将返回值写入了servletserverHttpResponse的出去流中
六 Spring Boot
6.1 介绍一下Spring Boot
Spring boot 是一个为了简化spring应用初始化配置的开源框架,来帮我们快速搭建Spring项目骨架。
优点是:
可以使用yaml文件来配置,比传统的propertirs文件更简洁
内嵌tomcat,不需要在服务器上部署war包
如果项目中添加了spring-boot-stater,springboot会自动配置Tomcat和Spring MVC
6.2 Spring Boot中自动配置原理了解吗?
在Spring中,自动配置是指容器利用反射技术,根据Bean的类型,名称等自动注入依赖
Spring Boot做了进一步的简化,直接通过SpringBootApplication注解一步搞定,这个注解里包含了EnableAutoConfigration注解
6.3 Spring Boot启动原理了解吗
Spring Boot应用通常有一个带有main方法的主类,这个类上标注了@SpringBootApplication注解它是整个应用启动的入口。这个注解组合了SpringBootConfiguration、EnableAutoConfiguration和componentScan,这些注解共同支持配置和类路径扫描
当执行main方法时,首先创建一个springApplication实例,负责管理Spring应用的启动和初始化
springApplication.run()方法负责准备和启动spring应用上下文applicationcontext环境:
扫描配置文件,添加依赖项
初始化和加载bean定义
启动内嵌tomcat容器
6.4 了解Springbootapplication注解吗
是一个组合注解,通常用在springboot的主类上,包括springbootconfiguration,Enableautoconfiguration:根据pom,xml文件中的依赖自动配置项目,componentscan,扫描当前包下被componet、controller、service注解标记的类,注册为Bean
6.5 为什么springboot在启动时能找到main方法上的springbootapplication注解
利用了java的反射机制和类加载机制
springapplication.run方法包含两个参数一个是应用主类,第二个是命令参数
springboot利用java反射机制读取run方法的应用主类,会检查这个类上的注解包括springbootapplication
6.6 Spring boot 默认的包扫描路径是什么
启动类注解springbootapplication所在的包为根目录
6.7 Springboot和spring mvc的区别
spring mvc是基于spring框架的一个模块,提供了一种mode-view-controller的开发模式
springboot旨在简化spring应用的配置和部署过程,提供了大量的自动配置选项,以及运行时环境内嵌的web服务器,可以快速开发一个springmvc的web项目